go 在网络编程中真的很香
什么是粘包分包:
集体了解,TCP 的流式传输会因为网络情况而导致接收端每次收到的数据和发送端每次发送的数据略有差异
e.g. 发送时为 {123} {456} 承受时为 {12} {3456}
办法 1:应用 websocket,无需解决
办法 2:失常 tcp 流程下应用长度法:
利用 time.Sleep(time.Nanosecond)来重现网络卡顿状况,复现粘包
服务端
func main(){listen , _ := net.Listen("tcp", "127.0.0.1:8888")
fmt.Println("start listen")
for {conn, err := listen.Accept()
if err!=nil {continue}
go process(conn)
}
}
func process(conn net.Conn) {fmt.Printf("new conn %d", conn.RemoteAddr())
// var buffer = make([]byte, 100)
for {reader := bufio.NewReader(conn)
peek, _ := reader.Peek(4)
buffer := bytes.NewBuffer(peek)
var length int32
binary.Read(buffer, binary.BigEndian, &length)
if int32(reader.Buffered()) < length+4 {continue}
data := make([]byte, length+4)
_, err := reader.Read(data)
if err!=nil {continue}
fmt.Println(string(data[4:]))
}
}
客户端
func main() {conn, err:= net.Dial("tcp", "127.0.0.1:8888")
if err!=nil {fmt.Println(err)
return
}
for i := 0; i < 100; i++{data, _ := Encode(time.Now().String())
conn.Write(data)
// time.Sleep(1*time.Second)
}
}
func Encode(message string) ([]byte, error) {var length = int32(len(message))
var pkg = new(bytes.Buffer)
err := binary.Write(pkg, binary.BigEndian, length)
if err!=nil {return nil, err}
err = binary.Write(pkg, binary.BigEndian, []byte(message))
if err!=nil {return nil, err}
return pkg.Bytes(), nil}