Network programming UDP sendto()何时阻塞?

Network programming UDP sendto()何时阻塞?,network-programming,udp,blocking,Network Programming,Udp,Blocking,在UDP套接字上使用默认(阻塞)行为时,在何种情况下,对sendto()的调用将阻塞?我主要对Linux的行为感兴趣 对于TCP,我知道如果发送窗口已满,拥塞控制会阻塞send()调用,但是UDP呢?它有时会阻止数据包还是让数据包在较低层被丢弃?这可能是因为您的操作系统正试图执行ARP请求以获取远程主机的硬件地址 基本上,每当数据包传出时,报头都需要远程主机的IP地址和远程主机(或到达它的第一个网关)的MAC地址。192.168.1.34和AB:32:24:64:F3:21 您的“阻塞”行为可能

在UDP套接字上使用默认(阻塞)行为时,在何种情况下,对sendto()的调用将阻塞?我主要对Linux的行为感兴趣


对于TCP,我知道如果发送窗口已满,拥塞控制会阻塞send()调用,但是UDP呢?它有时会阻止数据包还是让数据包在较低层被丢弃?

这可能是因为您的操作系统正试图执行ARP请求以获取远程主机的硬件地址

基本上,每当数据包传出时,报头都需要远程主机的IP地址和远程主机(或到达它的第一个网关)的MAC地址。192.168.1.34和AB:32:24:64:F3:21

您的“阻塞”行为可能是ARP正在工作


我在旧版本的Windows(我想是2k)中听说,如果请求时间太长,并且发送的数据太多,第一个数据包有时会被丢弃。从那时起,service pack可能已经解决了这一问题。

如果您填满了套接字缓冲区,可能会发生这种情况,但它高度依赖于操作系统。由于UDP不提供任何保证,所以当套接字缓冲区已满时,操作系统可以决定执行任何操作:阻塞或删除。您可以尝试增加SO_SNDBUF以获得临时缓解


这甚至可能取决于系统的微调,例如,它也可能取决于网络接口驱动程序中TX环的大小。在中有一些关于这方面的讨论,但是您确实希望与操作系统的开发人员讨论这一点。特别注意O_NONBLOCK和EAGAIN/ewooldblock。

Ok,回答元素好,有趣;但我最感兴趣的是与拥塞/满缓冲区相关的阻塞(或无阻塞)。ARP仅用于定位同一子网上的主机,通常是路由器。当IP数据包发出时,它需要远程主机的IP地址和下一跳的MAC地址……有人知道使用ioctlsocket()/fcntl()和FIONBIO/O_NONBLOCK是否可以防止发送套接字由于ARP查找而阻塞吗?@Ph0t0n-根据我的经验(在Windows中),如果在ARP条目超时时尝试执行send(),则会丢弃第一个IP数据包,并发送ARP请求。如果您使用的是TCP,该协议的错误恢复将启动并保存您。如果您使用的是UDP,那么您的数据包就丢失了。这与send()是否阻止您完全正交。对于TCP,我可以看到如果您在一次发送()中发送大量数据,它可能会发生什么情况。有关更多信息,请参阅我关于UDP和ARP的问题。好的,根据您的链接,我在上找到了linux特定的解释。这么简单的回答:Linux会在一个完整的发送缓冲区上阻止sendto。好的,但是现在这个问题被进一步推了一步:在什么条件下Linux会让套接字缓冲区填满?(与从中删除数据包相反)。不幸的是,这是一个非常困难的问题。@MarcH,recv怎么样,当套接字阻塞时发送?“我认为在这种情况下,发送和接收无论如何都会被阻止?”根据DS的回答,MarcH说。UDP套接字的
SO\u SNDBUF
似乎是UDP数据包的上限(因此
sendto()
从不阻塞)。或者你认为他所说的对UNIX有效而对Linux无效吗?谢谢