【问题标题】:how do sockets not missing arriving data?套接字如何不丢失到达的数据?
【发布时间】:2013-08-21 13:42:02
【问题描述】:

一个典型的套接字程序示例如下:

while(1){
   data = socket.recv()
   //do some work
}

由于你不知道包什么时候到达,所以它必须阻塞等待从监听端口获取一些数据,假设程序在收到另一端的命令后开始繁重的工作,在工作期间,另一个包到达,但是因为那一刻你在做工作,你没有监听端口,无论你处理工作多快,你都可能错过包。

那么套接字如何处理所有数据而不丢失任何数据?

【问题讨论】:

  • 它被称为“缓冲区”。

标签: sockets networking


【解决方案1】:

操作系统有一个receivebuffer,它保存着从网络收到但应用程序尚未recv()ed 的数据包。如果该缓冲区填满,数据包将丢失。当数据包到达时,您不必在recv() 调用中,但您应该确保调用它的频率足以防止缓冲区溢出。

【讨论】:

  • 这很外行。数据包总是丢失。网络、NIC、操作系统和应用程序上的缓冲区的组合允许您的应用程序在它不是专门寻找数据时从网络获取数据。当数据丢失时,如果这是所需的行为,则由网络协议(有时在低级协议(例如 TCP)中,有时在应用层中)重新发送这些数据包。您可能正在使用 TCP,它在应用层看不到“数据包”。
  • @xaxxon 你是对的。我已经编辑了我的答案,以不暗示接收缓冲区会阻止对数据包丢失的全面保护。
  • 如果接收缓冲区已满,如果您使用 UDP 而不是 TCP,则数据包会丢失。在 TCP 中,接收方确认接收到的数据,并告诉发送方在缓冲区空间不可用时停止发送新数据包。在发送端,TCP 会定期重新发送未确认的数据包,并在接收方不允许发送新数据时根据需要缓冲传出数据和/或阻塞发送代码。这一切都由 TCP 堆栈在两端为您处理。没有任何物理网络问题,TCP 不会丢失数据,如果确实丢失数据,则无论如何都需要重置连接。
  • @RemyLebeau 我假设使用 recv 意味着 OP 正在使用 UDP。但你是对的。我直接并且非常简单地回答了这个问题。这里肯定还有很多话要说。我很惊讶没有人提出更好,更详细的答案! ;-)
  • recv() 最常用于 TCP,但也可用于面向连接的 UDP。 recvfrom() 最常用于无连接 UDP,但也可用于 TCP 和面向连接的 UDP。
猜你喜欢
  • 2019-08-16
  • 2015-01-28
  • 2017-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多