我有一个应用程序通过可以在单工(单向传输)或双工模式(双向)操作的链路发送数据从发送器到接收器的点对点。在单工模式下,应用程序使用UDP发送数据,而在双工模式下,它使用TCP。由于TCP套接字上的写入可能会阻塞,因此我们使用非阻塞IO(ioctl与FIONBIO - O_NONBLOCK并且此分发不支持fcntl)和select()系统调用以确定何时可以写入数据。如果网络条件恶化,我们可以在超时后提前中止发送。我想使用相同的基本代码来进行发送,而是在更高抽象的TCP / UDP之间进行切换。这适用于TCP。
但是我担心Non Blocking IO如何用于UDP套接字。我可能正在错误地阅读手册页,但由于write()可能返回指示发送的字节数少于请求的数量,这是否意味着客户端将在其数据报中接收更少的字节?要发送给定的数据缓冲区,可能需要多次写入,这可能是因为我使用非阻塞IO。我担心这会转化为客户端收到的多个UDP数据报。
我对套接字编程相当新,所以如果在这里有一些误解,请原谅我。谢谢。
答案 0 :(得分:2)
假设一个正确的(未损坏的)UDP实现,那么每个send / sendmsg / sendto将对应于发送的整个数据报,每个recv / recvmsg / recvfrom将对应于接收到的整个数据报。
如果无法完整传输UDP消息,则应收到EMSGSIZE
错误。由于网络中某个点的大小,发送的消息可能仍然会失败,在这种情况下它将无法到达。但它不会分批交付(除非IP堆栈严重错误)。
一个好的经验法则是将UDP有效负载大小保持在最多1400字节。这是非常近似的,并为各种形式的隧道留下了很大的空间,以避免碎片化。