新聞中心
?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)
}
}
- ?
Server?端,接收到客戶端的數(shù)據(jù)后立即打印到終端上。 - ?
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ù)。 - 執(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


咨詢
建站咨詢
