c++ - 有时断开连接请求在发布消息中
问题描述
在客户端我使用:
mosquitto_pub -t tpc -m msg
在服务器端,我使用非阻塞套接字和socket()
API:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzab6/xnonblock.htm
第一次收到数据包后,我发送连接确认数据包。
对于每个接收到的数据包,我以十六进制打印接收到的字节数和整个缓冲区。
我将接收到的数据与 WireShark 捕获进行比较。
有时它运作良好:
37 bytes received - Connect Command
10 bytes received - Publish Message [tpc]
2 bytes received - Disconnect Req
有时我在Publish Message [tpc]中得到Disconnect Req:
37 bytes received - Connect Command
12 bytes received - Publish Message [tpc] + Disconnect Req
最后两个字节是Disconnect Req:
30
8
0
3
74
70
63
6d
73
67
ffffffe0 <--
0 <--
如何避免这些情况并始终获得 3 个数据包?
解决方案
简短的回答:你不能。您必须实际解析消息以确定长度。
调用创建 tcp 套接字的常量是SOCK_STREAM
有原因的。必须将套接字视为:字节流。没有人保证send()
一方面的结果会导致另一方面的结果recv()
。唯一的保证是保留序列:abcd
可能变成 ( ab
, cd
),但不会变成acbd
。数据包可能会在中途被拆分。因此,可能是客户端发送了 2048 个字节,但在服务器端,您将首先收到 ~1400 个字节,然后是其余的。所以 N send
s 不会导致 N recv
。
另一件事是客户端也将套接字视为流。它可以逐字节发送,也可以用一个发送一批消息send()
。N
消息不是 N send
s。