日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)GoFrame教程:GoFrame連接對(duì)象-基本介紹

?gtcp?模塊提供了簡便易用的?gtcp.Conn?鏈接操作對(duì)象。

我們擁有10年網(wǎng)頁設(shè)計(jì)和網(wǎng)站建設(shè)經(jīng)驗(yàn),從網(wǎng)站策劃到網(wǎng)站制作,我們的網(wǎng)頁設(shè)計(jì)師為您提供的解決方案。為企業(yè)提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計(jì)、成都做手機(jī)網(wǎng)站、H5場(chǎng)景定制、等業(yè)務(wù)。無論您有什么樣的網(wǎng)站設(shè)計(jì)或者設(shè)計(jì)方案要求,我們都將富于創(chuàng)造性的提供專業(yè)設(shè)計(jì)服務(wù)并滿足您的需求。

使用方式:

import "github.com/GOgf/gf/v2/net/gtcp"

接口文檔:

https://pkg.go.dev/github.com/gogf/gf/v2/net/gtcp

type Conn
    func NewConn(addr string, timeout ...int) (*Conn, error)
    func NewConnByNetConn(conn net.Conn) *Conn
    func NewConnKeyCrt(addr, crtFile, keyFile string) (*Conn, error)
    func NewConnTLS(addr string, tlsConfig *tls.Config) (*Conn, error)
    func (c *Conn) Close() error
    func (c *Conn) LocalAddr() net.Addr
    func (c *Conn) Recv(length int, retry ...Retry) ([]byte, error)
    func (c *Conn) RecvLine(retry ...Retry) ([]byte, error)
    func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry) ([]byte, error)
    func (c *Conn) RemoteAddr() net.Addr
    func (c *Conn) Send(data []byte, retry ...Retry) error
    func (c *Conn) SendRecv(data []byte, receive int, retry ...Retry) ([]byte, error)
    func (c *Conn) SendRecvWithTimeout(data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error)
    func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retry) error
    func (c *Conn) SetDeadline(t time.Time) error
    func (c *Conn) SetRecvBufferWait(bufferWaitDuration time.Duration)
    func (c *Conn) SetRecvDeadline(t time.Time) error
    func (c *Conn) SetSendDeadline(t time.Time) error

寫入操作

?TCP?通信寫入操作由?Send?方法實(shí)現(xiàn),并提供了錯(cuò)誤重試的機(jī)制,由第二個(gè)非必需參數(shù)?retry?提供。需要注意的是?Send?方法不帶任何的緩沖機(jī)制,也就是說每調(diào)用一次?Send?方法將會(huì)立即調(diào)用底層的?TCP Write?方法寫入數(shù)據(jù)(緩沖機(jī)制依靠系統(tǒng)底層實(shí)現(xiàn))。因此,如果想要進(jìn)行輸出緩沖控制,請(qǐng)?jiān)跇I(yè)務(wù)層進(jìn)行處理。

在進(jìn)行?TCP?寫入時(shí),可靠的通信場(chǎng)景下往往是一寫一讀,即?Send?成功之后接著便開始?Recv?獲取目標(biāo)的反饋結(jié)果。因此?gtcp.Conn?也提供了方便的?SendRecv?方法。

讀取操作

?TCP?通信讀取操作由?Recv?方法實(shí)現(xiàn),同時(shí)也提供了錯(cuò)誤重試的機(jī)制,由第二個(gè)非必需參數(shù)?retry?提供。?Recv?方法提供了內(nèi)置的讀取緩沖控制,讀取數(shù)據(jù)時(shí)可以指定讀取的長度(由?length?參數(shù)指定),當(dāng)讀取到指定長度的數(shù)據(jù)后將會(huì)立即返回。如果?length < 0?那么將會(huì)讀取所有可讀取的緩沖區(qū)數(shù)據(jù)并返回。當(dāng)?length = 0?時(shí)表示獲取一次緩沖區(qū)的數(shù)據(jù)后立即返回。

如果使用?Recv(-1)?可以讀取所有緩沖區(qū)可讀數(shù)據(jù)(長度不定,如果發(fā)送的數(shù)據(jù)包太長有可能會(huì)被截?cái)?,但需要注意包的解析問題,容易產(chǎn)生非完整包的情況。這個(gè)時(shí)候,業(yè)務(wù)層需要根據(jù)既定的數(shù)據(jù)包結(jié)構(gòu)自己負(fù)責(zé)包的完整性處理。推薦使用后續(xù)介紹的簡單協(xié)議通過?SendPkg/RecvPkg?來實(shí)現(xiàn)消息包的發(fā)送/接收。

超時(shí)處理

?gtcp.Conn?對(duì)?TCP?通信時(shí)的數(shù)據(jù)寫入和讀取提供了超時(shí)處理,通過方法中的?timeout?參數(shù)指定,這塊比較簡單,不過多闡述。

我們接下來通過通過幾個(gè)例子來看看如何使用?gtcp.Conn?對(duì)象。

使用示例

示例1,簡單使用

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/net/gtcp"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/v2/util/gconv"
)

func main() {
    // Server
    go gtcp.NewServer("127.0.0.1:8999", func(conn *gtcp.Conn) {
        defer conn.Close()
        for {
            data, err := conn.Recv(-1)
            if len(data) > 0 {
                  fmt.Println(string(data))
            }
            if err != nil {
                break
            }
        }
    }).Run()

    time.Sleep(time.Second)

    // Client
    conn, err := gtcp.NewConn("127.0.0.1:8999")
    if err != nil {
        panic(err)
    }
    for i := 0; i < 10000; i++ {
        if err := conn.Send([]byte(gconv.String(i))); err != nil {
            glog.Error(err)
        }
        time.Sleep(time.Second)
    }
}

  1. ?Server?端,接收到客戶端的數(shù)據(jù)后立即打印到終端上。
  2. ?Client?端,使用同一個(gè)連接對(duì)象,在循環(huán)中每隔1秒向服務(wù)端發(fā)送當(dāng)前遞增的數(shù)字。同時(shí),該功能也可以演示出底層?Socket?通信并沒有使用緩沖實(shí)現(xiàn),也就是說,執(zhí)行一次?Send?即立刻向服務(wù)端發(fā)送數(shù)據(jù)。因此,客戶端需要在本地自行管理好需要發(fā)送的緩沖數(shù)據(jù)。
  3. 執(zhí)行結(jié)果 執(zhí)行后,可以看到?Server?在終端上輸出以下信息:
 2018-07-11 22:11:08.650 0
 2018-07-11 22:11:09.651 1
 2018-07-11 22:11:10.651 2
 2018-07-11 22:11:11.651 3
 2018-07-11 22:11:12.651 4
 2018-07-11 22:11:13.651 5
 2018-07-11 22:11:14.652 6
 2018-07-11 22:11:15.652 7
 2018-07-11 22:11:16.652 8
 2018-07-11 22:11:17.652 9
 2018-07-11 22:11:18.652 10
 2018-07-11 22:11:19.653 11
 ...

示例2,回顯服務(wù)

我們將之前的回顯服務(wù)改進(jìn)一下:

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/net/gtcp"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/v2/os/gtime"
)

func main() {
    // Server
    go gtcp.NewServer("127.0.0.1:8999", func(conn *gtcp.Conn) {
        defer conn.Close()
        for {
            data, err := conn.Recv(-1)
            if len(data) > 0 {
                if err := conn.Send(append([]byte("> "), data...)); err != nil {
                  fmt.Println(err)
                }
            }
            if err != nil {
                break
            }
        }
    }).Run()

    time.Sleep(time.Second)

    // Client
    for {
       if conn, err := gtcp.NewConn("127.0.0.1:8999"); err == nil {
           if b, err := conn.SendRecv([]byte(gtime.Datetime()), -1); err == nil {
               fmt.Println(string(b), conn.LocalAddr(), conn.RemoteAddr())
           } else {
               fmt.Println(err)
           }
           conn.Close()
       } else {
           glog.Error(err)
       }
       time.Sleep(time.Second)
    }
}

該示例程序中,?Client?每隔1秒鐘向?Server?發(fā)送當(dāng)前的時(shí)間信息,?Server?接收到之后返回原數(shù)據(jù)信息,?Client?接收到?Server?端返回信息后立即打印到終端。

執(zhí)行后,輸出結(jié)果為:

> 2018-07-19 23:25:43 127.0.0.1:34306 127.0.0.1:8999
> 2018-07-19 23:25:44 127.0.0.1:34308 127.0.0.1:8999
> 2018-07-19 23:25:45 127.0.0.1:34312 127.0.0.1:8999
> 2018-07-19 23:25:46 127.0.0.1:34314 127.0.0.1:8999

示例3,HTTP客戶端

我們?cè)谶@個(gè)示例中使用?gtcp?包來實(shí)現(xiàn)一個(gè)簡單的?HTTP?客戶端,讀取并打印出百度首頁的?header?和?content?內(nèi)容。

package main

import (
    "fmt"
    "bytes"
    "github.com/gogf/gf/v2/net/gtcp"
    "github.com/gogf/gf/v2/util/gconv"
)

func main() {
    conn, err := gtcp.NewConn("www.baidu.com:80")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    if err := conn.Send([]byte("GET / HTTP/1.1\r\n\r\n")); err != nil {
        panic(err)
    }

    header        := make([]byte, 0)
    content       := make([]byte, 0)
    contentLength := 0
    for {
        data, err := conn.RecvLine()
        // header讀取,解析文本長度
        if len(data) > 0 {
            array := bytes.Split(data, []byte(": "))
            // 獲得頁面內(nèi)容長度
            if contentLength == 0 && len(array) == 2 && bytes.EqualFold([]byte("Content-Length"), array[0]) {
                contentLength = gconv.Int(string(array[1][:len(array[1])-1]))           }
            header = append(header, data...)
            header = append(header, '\n')
        }
        // header讀取完畢,讀取文本內(nèi)容
        if contentLength > 0 && len(data) == 1 {
            content, _ = conn.Recv(contentLength)
            break
        }
        if err != nil {
            fmt.Errorf("ERROR: %s\n", err.Error())
            break
        }
    }

    if len(header) > 0 {
        fmt.Println(string(header))
    }
    if len(content) > 0 {
        fmt.Println(string(content))
    }
}

執(zhí)行后,輸出結(jié)果為:

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 14615
Content-Type: text/html
Date: Sat, 21 Jul 2018 04:21:03 GMT
Etag: "5b3c3650-3917"
Last-Modified: Wed, 04 Jul 2018 02:52:00 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
...
(略)

網(wǎng)站標(biāo)題:創(chuàng)新互聯(lián)GoFrame教程:GoFrame連接對(duì)象-基本介紹
標(biāo)題網(wǎng)址:http://www.dlmjj.cn/article/djipojg.html