请教Asyncsocket网络编程 怎么处理粘包问题
2016-10-12
展开全部
//粘包问题演示服务端
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)
}
}
复制代码
运行后查看服务端输出:
可以看到json格式的字符串都粘到一起了,有种淡淡的忧伤了——头疼的事情又来了。
粘包产生原因
关于粘包的产生原因网上有很多相关的说明,主要原因就是tcp数据传递模式是流模式,在保持长连接的时候可以进行多次的收和发。如果要深入了解可以看看tcp协议方面的内容。
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)
}
}
复制代码
运行后查看服务端输出:
可以看到json格式的字符串都粘到一起了,有种淡淡的忧伤了——头疼的事情又来了。
粘包产生原因
关于粘包的产生原因网上有很多相关的说明,主要原因就是tcp数据传递模式是流模式,在保持长连接的时候可以进行多次的收和发。如果要深入了解可以看看tcp协议方面的内容。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询