UDP recvfrom查询

UDP recvfrom query

int recvfrom(SOCKET            socket, 
             char            * buffer, 
             int               buflen, 
             int               flags, 
             struct sockaddr * from, 
             int             * fromlen);

我知道 recvfrom() returns 从套接字读取 buflen 后立即。我的问题是 -

  1. 如果我请求了 2000 的 buflen 并且套接字队列中的单个数据包大小为 2400 怎么办?

  2. 如果我请求了 buflen 个 2000 并且套接字队列中的单个数据包大小为 1400 怎么办?

  3. 上述问题的答案对 TCP 和 UDP 是否同样适用?如果不是,有什么区别

感谢提前回复。

recvfrom() 从套接字读取最多 buflen。它可以读得更少,这就是为什么你应该经常检查 return 值。

1) 它会将 2000 个字节复制到您的缓冲区中。对于 UDP,多余的数据将丢失。对于 TCP,您应该可以通过再次调用 recvfrom().

来接收它

2) 它会将 1400 个字节复制到您的缓冲区中。

3) 通常recvfrom()用于UDP,recv()用于TCP,但其他行为与上述相同。

首先,recvfrom() 只有 returns 立即 如果已经有东西等待读取,或者套接字处于非阻塞模式。否则,它等待数据到达。

其次,UDP 是孤注一掷的。与 TCP 对流数据进行操作不同,UDP 对数据报进行操作,数据报不能分段读取。

所以,回答你的问题:

  1. 2000 字节将被复制到您的缓冲区中,剩余的 400 字节将被丢弃和丢失,因为您的缓冲区太小无法接收完整的数据报。 recvfrom()会报EMSGSIZE错误。

  2. 您的缓冲区足够大,可以接收完整的数据报,因此 1400 字节将被复制到您的缓冲区中。 recvfrom()会报成功

  3. 这些不适用于TCP。首先,您通常不会对 TCP 使用 recvfrom(),而是使用 recv()。但在任何一种情况下,在 TCP 中,recv/from() 接收当时 当前可用 的任何字节,如果需要则阻塞,直到指定的字节数但可能更少。您可以继续调用 recv/from() 来接收剩余的字节,因为 TCP 是基于流的。由于 UDP 是基于消息的,您无法接收剩余的字节,它们会丢失。下一个 recv/from() 将读取下一个可用的数据报。