我有点通过Unix套接字(TCP本地)插槽清洗
弄得我有一个服务器和客户:
- 客户通过套接字发送一些信息到服务器(使用
send
) 多次 - 服务器打印此数据(se rver致电
recv
接收它)。
的问题是,服务器版画不仅我想,插座在某种程度上这是由客户发送的最后信息,但一些老的信息(有时损坏)从此客户太多,所以通过客户端积累了所有写入它的以前的数据。
如何才能服务器只接收从客户端最后的数据?我应该以某种方式清理套接字,否则我应该一直关闭它并创建新的(非常糟糕的解决方案)?
我有点通过Unix套接字(TCP本地)插槽清洗
弄得我有一个服务器和客户:
send
) 多次recv
接收它)。的问题是,服务器版画不仅我想,插座在某种程度上这是由客户发送的最后信息,但一些老的信息(有时损坏)从此客户太多,所以通过客户端积累了所有写入它的以前的数据。
如何才能服务器只接收从客户端最后的数据?我应该以某种方式清理套接字,否则我应该一直关闭它并创建新的(非常糟糕的解决方案)?
TCP套接字是流套接字。
这意味着您发送的所有数据不会被视为一系列消息,而会被视为一系列字节。这些字节是按顺序接收的,没有增加或省略,但不一定在相同的块中。
例如,如果您的客户端每次调用send
3次,每次1000字节,则无法知道recv
将返回数据的次数。它可能会返回3次,每个1000字节,或者只有一次3000字节,或理论上甚至3000次,每次1字节。
对ugoren刚才所说的+1。您需要检查recv()的返回值以确定您实际获得的字节数。许多套接字程序员犯的最大错误是假定“recv()”将返回与传递给“send()”相同数量的字节。 – selbie 2013-04-26 20:16:58
图像发送/接收的字节放置在一个队列(内部缓冲区)中。如果您拨打send()
两次,每次发送10个字节,则缓冲区中将有20个字节。当另一方调用recv()
时,它将从该队列中取出若干字节并将它们放入数组中。多少字节?直到可用(20)或更少。
例如,如果调用
nb = recv(socket, arr, 15,...);
那么只有15个字节将被消耗(大概您的阵列arr
有这个长度)时,它们将被复制到arr
,nb
将是15,并在内部我们留下了5个字节的缓冲区。
如果相反,我们会打电话
nb = recv(socket, arr, 100,...);
那么20个字节数据将被复制到arr
,nb
将是20,和内部缓冲区将是空的。
这显示这一点:
send()
/recv()
电话是不在一个一一对应
你必须经常检查recv
回报(nb
)知道有多少字节是读
你可以不知道哪些字节是在每个发送电话。的“信息”的界定是你
你是不读的消息,也没有字符串(空值终止字符数组),你只是读取字节。然后,你不能只是叫printf("%s",arr)
看到接收的字节
TCP是流协议;
检查send和recv的返回值,确保差错已得到妥善处理;
检查你打印的是你送什么,检查二进制内容和长度发送和recv缓冲区。
确保您在发送方发送的内容是您在接收方获得的内容。
和一块代码是公理解用于进一步分析。
你能发布代码吗?尽管保留它[SSCCE](http://sscce.org/)! – Kninnug 2013-04-26 19:39:21
它不能。例外是具有缓冲区溢出的UDP,但它无论如何都做你想要避免的 – 2013-04-26 19:39:36
TCP连接创建没有明确界限的数据流。数据边界是应用程序定义的。您的应用程序必须准备好进行部分接收操作,并能够检测到接收完整数据的时间。这意味着它可能需要多次调用recv函数来接收由对等方发送的完整数据。 – 2013-04-26 19:42:30