sockets - C : what do I get? 中的非阻塞 udp 套接字编程

标签 sockets tcp udp blocking nonblocking

我无法理解 recv()/recvfrom() 从非阻塞 UDP 套接字返回的内容。

与 TCP 相比更具体一些(如果我错了请纠正我):

  • 在缓冲区中有一些数据之前,阻塞套接字(TCP 或 UDP)不会从 recv() 返回。这可能是一些字节数 (TCP) 或完整的数据报 (UDP)。

  • 非阻塞 TCP 套接字返回 EWOULDBLOCK (linux)/WSAEWOULDBLOCK (windows) 或当前缓冲区中的字节。由于 TCP 数据是一个流,因此返回多少字节并不重要。

现在问题:

  • 如果没有可用数据,非阻塞 UDP 套接字也会返回 WOULDBLOCK (linux)/WSAEWOULDBLOCK (windows)。但是,如果有数据可用,非阻塞 UDP 套接字是否只返回一些字节,这可能意味着您只能获得数据报的一半,或者 UDP 套接字是否总是返回完整的数据报?

编辑:

“数据报的一半”的意思是:如果我在套接字当前正在接收数据报的那一刻调用 recv() 会发生什么。在那一刻,缓冲区中有一些字节,但数据报尚未完成。

感谢您的解释和评论。谢谢!

最佳答案

终于有借口从我的旧办公室箱子里翻出我的史蒂文斯书籍了。

如果缓冲区足够大,标准 Berkeley 套接字 recv()recvfrom() 函数永远不会返回部分数据报。在内核完全接收并重新组装数据报之前,应用程序无法使用该数据报。

有趣的是,这在今天不是什么大问题,当提供的缓冲区太小时,其他网络编程接口(interface)不同意行为:

The traditional Berkeley version of the sockets API truncates the datagram, discarding any excess data. Whether the application is notified depends on the version. (4.3BSD Reno and later can notify the application that the datagram was truncated.)

The sockets API under SVR4 (including Solaris 2.x) does not truncate the datagram. Any excess data is returned in subsequent reads. The application is not notified that multiple reads are being fulfilled from a single UDP datagram.

The TLI API does not discard the data. Instead a flag is returned indicating that more data is available, and subsequent reads by the application return the rest of the datagram.

(Stevens,TCP/IP Illustrated,第 1 卷,第 160 页)

关于sockets - C : what do I get? 中的非阻塞 udp 套接字编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2239986/

相关文章:

c++ - 通过 tcp 套接字发送数据时出现错误的文件描述符错误

linux - golang udp 连接在每次写入时都被拒绝

ios - 如何在特定接口(interface)上接收 UDP 广播数据包?

java - 通过WIFI高速传输文件

c# - 如何改善这个TCP代码?

c# - 为什么我的客户端/服务器代码不能在我的本地机器之外工作?

linux - super 终端使用的TCP/IP通信协议(protocol)?

c++ - 将 RTP 流数据写入文件

android - 如何通过 Socket 传输 Android 对象?

c++ - 从 TCP 客户端发送的双数组