用 C 语言进行非阻塞 udp 套接字编程:我能得到什么?

发布于 2024-08-21 04:54:35 字数 605 浏览 8 评论 0原文

我在理解从非阻塞 UDP 套接字返回什么recv()/recvfrom() 时遇到问题。

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

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

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

现在的问题是:

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

编辑:

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

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

I have a problem in understanding what recv()/recvfrom() return from an non-blockig UDP socket.

A bit more specific and compared to TCP (please correct me if I'm wrong):

  • A blocking socket (either TCP or UDP) won't return from a recv() until there is some data in the buffer. This could be some number of bytes (TCP) or a complete datagram (UDP).

  • A non-blocking TCP socket either returns EWOULDBLOCK (linux) / WSAEWOULDBLOCK (windows) or the bytes that are currently in the buffer. As TCP data is a stream it doesn't matter how many bytes are returned.

Now the question:

  • A non-blocking UDP socket also returns WOULDBLOCK (linux) / WSAEWOULDBLOCK (windows) if there is no data available. But if there is data availabe, does a non-blocking UDP socket return just some bytes, which could mean you only get half of a datagram OR does an UDP socket always return complete datagrams??

Edit:

What I mean with "half of a datagram" is: what happens if I call recv() in just the moment when the socket is currently receiving a datagram. In that moment there are some bytes in the buffer but the datagram isn't complete yet.

Your explanations and comments are appreciated. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

超可爱的懒熊 2024-08-28 04:54:35

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

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

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

传统的 Berkeley 版本的套接字 API 会截断数据报,丢弃任何多余的数据。是否通知应用程序取决于版本。 (4.3BSD Reno及更高版本可以通知应用程序数据报被截断。)

SVR4(包括 Solaris 2.x)下的套接字 API 不会截断数据报。任何多余的数据都会在后续读取中返回。应用程序不会收到关于从单个 UDP 数据报完成多次读取的通知。

TLI API 不会丢弃数据。相反,会返回一个标志,指示有更多数据可用,并且应用程序的后续读取将返回数据报的其余部分。

(史蒂文斯,《TCP/IP 插图》,第 1 卷,第 160 页)

Finally, an excuse to dig out my Stevens books from my old office boxes.

Provided the buffer is large enough, the standard Berkeley sockets recv() and recvfrom() functions will never return a partial datagram. The datagram is not available to the application until the kernel has completely received and reassembled the datagram.

Interestingly, and this isn't much (any?) of an issue today, other network programming interfaces don't agree on the behavior when the provided buffer is too small:

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, Volume 1, p. 160)

忘东忘西忘不掉你 2024-08-28 04:54:35

是的,UDP 仅返回在该数据报中传输的数据。 UDP 不像 TCP 那样面向流。数据报是离散传输,并且不以任何方式真正与其他数据报相关联。这就是 TCP 的套接字选项是 SOCK_STREAM 的原因。

这样做的好处是您可以感受到单独的传输,而这对于 TCP 来说并不容易做到。

Yes, UDP just returns what data got transmitted in that one datagram. UDP is not stream-oriented like TCP. Datagrams are discrete transmissions, and are not really tied to other datagrams in any way. That's the reason the socket option for TCP is SOCK_STREAM.

The bright side of this is that you can get a sense of separate transmissions, which isn't really easy to do with TCP.

找个人就嫁了吧 2024-08-28 04:54:35

我相信您会得到精确的一个或零个数据报。但我现在无法支持这一点。也许其他人可以提供一个很好的参考?

编辑:我很确定你收不到半个数据报。数据报要么已到达缓冲区,要么尚未到达。

I believe you get precisely one or zero datagrams. But I can't back this up at this moment. Perhaps someone else could provide a good reference?

Edit: I'm pretty sure you can't receive half a datagram. Either the datagram has arrived in the in buffer, or it hasn't.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文