2

这是我在这里的第一条信息。我正在实时操作系统(OnTime 和 VxWorks)上使用非阻塞 UDP 套接字。我已经阅读了文档和一些论坛,但我对 sendto() 和 recvfrom() 函数的“原子性”有一些疑问:

  • sendto() 返回排队或错误的字节数。它是否可能小于输入缓冲区长度?也许输出缓冲区没有足够的可用空间,只有几个字节排队......

  • recvfrom() 返回接收到的字节数或错误。它是否可能小于源发送的消息的大小?我的意思是部分消息阅读...

我希望读写函数是原子的(完整的消息或没有消息读/写)。

谢谢。伊曼纽尔。


我询问了 OnTime 支持,他们告诉我,如果输出缓冲区没有足够的可用空间,sendto() 可能会将部分消息排入队列。我不知道 recvfrom() 在某些情况下是否也可以返回部分消息。我想不同操作系统之间的套接字实现没有标准行为。

4

2 回答 2

1

sendto() 返回排队或错误的字节数。它是否可能小于输入缓冲区长度?

不,它是完全发送的,或者根本不发送 UDP。

recvfrom() 返回接收到的字节数或错误。它是否可能小于源发送的消息的大小?我的意思是部分消息阅读...

如果操作系统堆栈的缓冲区不能容纳整个 UDP 数据包,则将其丢弃。如果您的应用程序缓冲区无法容纳整个数据包,您将获得数据包的初始内容。

即,您只能在一种情况下读取部分消息,即如果数据不适合您传递给 sendto() 的缓冲区。在这种情况下,数据包的其余部分将被丢弃。使用 recvmsg() 您可以检测数据包是否被截断,但这通常可以通过使用最大大小的缓冲区(UDP 必须适合 MTU 为 2^16-1 的 IP 数据包)或通过设计您使用的协议来解决在 UDP 内部,您可以在其中设置自己的合理最大大小。

于 2013-01-14T15:04:26.843 回答
0

我对这些系统并不是很熟悉,但是如果它们破坏了正常的 UDP 套接字语义,我会感到非常惊讶,这总是在“发送”时将完整的数据报入队并在“接收”时将完整的单个数据报出队。

于 2013-01-14T15:06:42.763 回答