Golang Tcp粘包處理(轉) -开发者知识库

Golang Tcp粘包處理(轉) -开发者知识库,第1张

在用golang開發人工客服系統的時候碰到了粘包問題,那么什么是粘包呢?例如我們和客戶端約定數據交互格式是一個json格式的字符串:

{"Id":1,"Name":"golang","Message":"message"}

當客戶端發送數據給服務端的時候,如果服務端沒有及時接收,客戶端又發送了一條數據上來,這時候服務端才進行接收的話就會收到兩個連續的字符串,形如:

{"Id":1,"Name":"golang","Message":"message"}{"Id":1,"Name":"golang","Message":"message"}

如果接收緩沖區滿了的話,那么也有可能接收到半截的json字符串,醬紫的話還怎么用json解碼呢?真是頭疼。以下用golang模擬了下這個粘包的產生。

備注:下面貼的代碼均可以運行於golang 1.3.1,如果發現有問題可以聯系我。

粘包示例

server.go

//粘包問題演示服務端
package main

import (
"fmt"
"net"
"os"
)

func main() {
netListen, err := net.Listen("tcp", ":9988")
CheckError(err)

defer netListen.Close()

Log("Waiting for clients")
for {
conn, err := netListen.Accept()
if err != nil {
continue
}

Log(conn.RemoteAddr().String(), " tcp connect success")
go handleConnection(conn)
}
}

func handleConnection(conn net.Conn) {
buffer := make([]byte, 1024)
for {
n, err := conn.Read(buffer)
if err != nil {
Log(conn.RemoteAddr().String(), " connection error: ", err)
return
}
Log(conn.RemoteAddr().String(), "receive data length:", n)
Log(conn.RemoteAddr().String(), "receive data:", buffer[:n])
Log(conn.RemoteAddr().String(), "receive data string:", string(buffer[:n]))
}
}

func Log(v ...interface{}) {
fmt.Println(v...)
}

func CheckError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}

client.go

//粘包問題演示客戶端
package main

import (
"fmt"
"net"
"os"
"time"
)

func sender(conn net.Conn) {
for i := 0; i < 100; i {
words := "{\"Id\":1,\"Name\":\"golang\",\"Message\":\"message\"}"
conn.Write([]byte(words))
}
}

func main() {
server := "127.0.0.1:9988"
tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}

conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}

defer conn.Close()

fmt.Println("connect success")

go sender(conn)

for {
time.Sleep(1 * 1e9)
}
}

運行后查看服務端輸出:

Golang Tcp粘包處理(轉) -开发者知识库,golang粘包問題演示,第2张

golang粘包問題演示

最佳答案:

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复