C中的非阻塞udp套接字编程:我得到了什么? [英] non-blocking udp socket programming in C: what do I get?

查看:34
本文介绍了C中的非阻塞udp套接字编程:我得到了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

  • 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).

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

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.

现在的问题:

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

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

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!

推荐答案

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

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

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

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:

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

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.)

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

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.

TLI API 不会丢弃数据.而是返回一个标志,指示更多数据可用,应用程序的后续读取将返回数据报的其余部分.

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.

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

(Stevens, TCP/IP Illustrated, Volume 1, p. 160)

这篇关于C中的非阻塞udp套接字编程:我得到了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆