我正在 GO 中创建一个 TCP 服务器端,它接收 TCP 数据包并相应地发送响应。我能够监听连接,但是当客户端向服务器发送 TCP 数据包时,服务器仅在连接重置(TCP RST)时才会接收它们。这意味着当客户端发送数据包时,服务器会等待下一个数据包对第一个数据包进行处理。这是影响这部分问题的代码:listener, err := net.Listen("tcp", ":25565")if err != nil { fmt.Println(err)}for { conn, err := listener.Accept() if err != nil { fmt.Println(err) } message, _ := ioutil.ReadAll(conn) // Get the bytes from the TCP packet fmt.Println("Received connection " + conn.RemoteAddr().String()) HandlePacket(conn, message) // Do stuff with the data conn.Close() // End the connection}HandlePacket(...)解析数据包中接收到的字节。问题是,当客户端发送第一个数据包时它什么也没收到,然后在发送第二个数据包时打印第一个数据包的数据。
1 回答
婷婷同学_
TA贡献1844条经验 获得超8个赞
重要的提示就在您从套接字读取的调用中:
message, _ := ioutil.ReadAll(conn) // Get the bytes from the TCP packet
ReadAll()不会只返回套接字缓冲区中的可用数据。ReadAll()将一直读取,直到再也没有数据要读取 - 直到流关闭。如您所见,仅当连接关闭时,流才会关闭。
您必须要求 TCP 套接字读取一些有限数量的数据。由于 TCP 不保留消息边界,因此您必须使用自己的成帧方案来知道要读取多少数据。
一种这样简单的方案是使您的数据包始终具有固定大小。这可能很有用,例如,如果您要为某个游戏的网络代码发送流更新;只需让每个数据包 256 字节,并在 256 字节中放入尽可能多的位置更新;如果有更多,只需发送更多数据包。
如果使用固定大小的帧对您不起作用,请考虑使用带有小标题的数据包。也许前 4 个字节是一个整数,告诉您消息的长度,然后是消息。然后,每次要读取数据包时,执行 4 个字节的硬读取以找出大小,然后从套接字读取那么多字节。
- 1 回答
- 0 关注
- 294 浏览
添加回答
举报
0/150
提交
取消
