2013-04-26 69 views
0

我有点通过Unix套接字(TCP本地)插槽清洗

弄得我有一个服务器客户

  • 客户通过套接字发送一些信息到服务器(使用send) 多次
  • 服务器打印此数据(se rver致电recv接收它)。

的问题是,服务器版画不仅我想,插座在某种程度上这是由客户发送的最后信息,但一些老的信息(有时损坏)从此客户太多,所以通过客户端积累了所有写入它的以前的数据

如何才能服务器只接收从客户端最后的数据?我应该以某种方式清理套接字,否则我应该一直关闭它并创建新的(非常糟糕的解决方案)?

+1

你能发布代码吗?尽管保留它[SSCCE](http://sscce.org/)! – Kninnug 2013-04-26 19:39:21

+0

它不能。例外是具有缓冲区溢出的UDP,但它无论如何都做你想要避免的 – 2013-04-26 19:39:36

+0

TCP连接创建没有明确界限的数据流。数据边界是应用程序定义的。您的应用程序必须准备好进行部分接收操作,并能够检测到接收完整数据的时间。这意味着它可能需要多次调用recv函数来接收由对等方发送的完整数据。 – 2013-04-26 19:42:30

回答

3

TCP套接字是流套接字。
这意味着您发送的所有数据不会被视为一系列消息,而会被视为一系列字节。这些字节是按顺序接收的,没有增加或省略,但不一定在相同的块中。

例如,如果您的客户端每次调用send 3次,每次1000字节,则无法知道recv将返回数据的次数。它可能会返回3次,每个1000字节,或者只有一次3000字节,或理论上甚至3000次,每次1字节。

+1

对ugoren刚才所说的+1。您需要检查recv()的返回值以确定您实际获得的字节数。许多套接字程序员犯的最大错误是假定“recv()”将返回与传递给“send()”相同数量的字节。 – selbie 2013-04-26 20:16:58

1

图像发送/接收的字节放置在一个队列(内部缓冲区)中。如果您拨打send()两次,每次发送10个字节,则缓冲区中将有20个字节。当另一方调用recv()时,它将从该队列中取出若干字节并将它们放入数组中。多少字节?直到可用(20)或更少。

例如,如果调用

nb = recv(socket, arr, 15,...); 

那么只有15个字节将被消耗(大概您的阵列arr有这个长度)时,它们将被复制到arrnb将是15,并在内部我们留下了5个字节的缓冲区。

如果相反,我们会打电话

nb = recv(socket, arr, 100,...); 

那么20个字节数据将被复制到arrnb将是20,和内部缓冲区将是空的。

这显示这一点:

  • send()/recv()电话是在一个一一对应

  • 你必须经常检查recv回报(nb)知道有多少字节是读

  • 你可以不知道哪些字节是在每个发送电话。的“信息”的界定是你

  • 你是不读的消息,也没有字符串(空值终止字符数组),你只是读取字节。然后,你不能只是叫printf("%s",arr)看到接收的字节

1
  1. TCP是流协议;

  2. 检查send和recv的返回值,确保差错已得到妥善处理;

  3. 检查你打印的是你送什么,检查二进制内容和长度发送和recv缓冲区。

确保您在发送方发送的内容是您在接收方获得的内容。

和一块代码是公理解用于进一步分析。