我对 unix 套接字(TCP 本地)有点困惑
我有一个服务器和一个客户端:
- 客户端
send
通过套接字(使用)多次向服务器发送一些信息 - 服务器打印此数据(服务器调用
recv
以接收它)。
问题是服务器不仅打印客户端发送的最后信息,还打印来自该客户端的一些旧信息(有时已损坏),所以我认为套接字以某种方式累积了客户端写入它的所有先前数据。
服务器如何只接收来自客户端的最后数据?我应该以某种方式清理套接字,还是应该一直关闭它并创建新的(非常糟糕的解决方案)?
TCP 套接字是流套接字。
这意味着您发送的所有数据都不会被视为消息序列,而是被视为字节序列。字节按顺序接收,没有添加或省略,但不一定在相同的块中。
例如,如果您的客户端调用send
3 次,每次调用 1000 个字节,您无法确定recv
返回数据的次数。它可能会返回 3 次,每次 1000 字节,或者只返回一次 3000 字节,或者理论上甚至 3000 次,每次 1 字节。
tcp is stream protocol;
check the return value of send and recv, make sure error has been properly handled;
check what you print is what you send, check send and recv buffer in binary content and length.
Make sure what you send at the sender side is what you will get at the receiver side.
And a piece of code is well appreciated for further analysis.
图像发送/接收的字节被放置在一个队列(内部缓冲区)中。如果调用send()
两次,每次发送 10 个字节,缓冲区中将有 20 个字节。当对方调用recv()
时,它将从该队列中取出一些字节并将它们放入传递的数组中。多少字节?最多可用 (20) 个或更少。
例如,如果您调用
nb = recv(socket, arr, 15,...);
然后只消耗 15 个字节(大概你的数组有这个长度) ,arr
它们将被复制到15 个字节中,并且在内部缓冲区中我们剩下 5 个字节。arr
nb
如果相反,我们会打电话给
nb = recv(socket, arr, 100,...);
然后 20 个字节将被复制到arr
,nb
将是 20,并且内部缓冲区将为空。
这向您表明:
send()
/recv()
调用不是一一对应的
您必须始终检查recv
return ( nb
) 以了解读取了多少字节
您无法知道每次send()
调用中发送了哪些字节。“消息”的界限由你决定
您不是在读取消息,也不是字符串(以空字符结尾的字符数组),您只是在读取字节。然后,您不能只调用printf("%s",arr)
查看接收到的字节