首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >插座清洗

插座清洗
EN

Stack Overflow用户
提问于 2013-04-26 19:36:56
回答 3查看 4.6K关注 0票数 0

我被unix套接字(TCP本地协议)弄糊涂了。

我有一个服务器和一个客户机

  • 客户端多次通过套接字(使用send)向服务器发送一些信息
  • 服务器打印此数据(服务器调用recv接收数据)。

问题是,服务器不仅打印client发送的最后信息,而且还打印来自客户端的一些旧信息(有时已损坏),因此我认为套接字以某种方式积累了client写入的所有以前的数据。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-26 20:12:06

TCP套接字是流套接字。

这意味着您发送的所有数据都不是作为消息序列处理,而是作为字节序列处理。字节是按顺序接收的,没有添加或遗漏,但不一定在相同的块中。

例如,如果客户端每次调用send 3次,每次调用1000个字节,则无法判断recv将返回多少次数据。它可以返回3次,每个返回1000字节,或者只返回一次,每次返回3000字节,或者理论上返回3000次,每次返回1字节。

票数 3
EN

Stack Overflow用户

发布于 2013-04-26 20:18:00

将发送/接收的字节放在队列中(内部缓冲区)。如果您调用send()两次,每次发送10个字节,缓冲区中将有20个字节。当另一方调用recv()时,它将从队列中取出许多字节,并将它们放在传递的数组中。多少字节?最多可得(20),或更少。

例如,如果你打电话给

代码语言:javascript
复制
   nb =  recv(socket, arr, 15,...);

然后只消耗15个字节(想必您的数组arr有此长度),它们将被复制到arr中,nb为15,而在内部缓冲区中只剩下5个字节。

如果我们给你打电话

代码语言:javascript
复制
   nb =  recv(socket, arr, 100,...);

然后将20个字节复制到arr中,nb为20,内部缓冲区为空。

这向你表明:

  • send()/recv()呼叫是一对一通信中的而不是
  • 您必须始终检查recv返回(nb)以知道读取了多少字节。
  • 您无法知道在每个send()调用中发送了哪些字节。“讯息”的界定由你决定。
  • 您不是在读取消息,也不是读取字符串(以null结尾的char数组),您只是在读取字节。然后,您不能只调用printf("%s",arr)来查看接收到的字节
票数 1
EN

Stack Overflow用户

发布于 2013-04-27 05:17:57

  1. tcp是流协议;
  2. 检查“发送”和“恢复”的返回值,确保错误得到正确处理;
  3. 检查您打印的是您发送的内容,检查send和recv缓冲区的二进制内容和长度。

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

对于进一步的分析来说,一段代码是很受欢迎的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16243975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档