了解套接字recv行为

时间:2013-05-02 12:21:36

标签: sockets unix

我正在阅读recv http://linux.die.net/man/2/recv的联机帮助页,但它并没有真正回答我的问题,所以我希望我能在这里得到一些答案。

我用这种方式调用recv:

numBytes = ::recv(getSocketId(), pData, nSize, MSG_DONTWAIT);

现在的问题是:

  1. 当包大于缓冲区时,recv将读取nSize字节并将其放在内存位置。 returnvalue将是nSize,对吗?我可以再次调用recv,直到收到所有数据。
  2. 当包小于nSize时,rcv将读取可用的字节数,然后返回值< nSize&& > = 0.或者会重新尝试等到实际收到nSize字节?如果我理解手册页是正确的,我认为情况并非如此(至少我希望如此)。或者recv将返回-1和errno = EAGAIN或EWOULDBLOCK?
  3. 如果recv返回-1,缓冲区会发生什么?在这种情况下它是否总是保持不变,或者可能是数据的一部分已被放入其中,但是我永远不会知道有多少字节被转移,所以我认为情况并非如此,对吧?
  4. 我想要的是,它读取尽可能多的字节数,然后返回,给我转移的字节数。在另一个层中,我将构建实际的消息,而不管它是如何收到的。但是,我不希望服务器卡在接收呼叫上,因为我不知道客户端正在做什么,它不应该有效地将服务器挂在一个连接上。

1 个答案:

答案 0 :(得分:4)

  
      
  1. 当包大于缓冲区时,recv将读取nSize字节并将其放在内存位置。 returnvalue将是nSize,对吗?我可以再次调用recv,直到收到所有数据。
  2.   

正确。

  
      
  1. 当包小于nSize时,rcv将读取可用的字节数,然后返回值< nSize&& > = 0。
  2.   

不完全。它将返回>如果有数据则为0;如果对等体已关闭连接则为0;如果存在错误,则为-1,或者如果没有数据且您处于非阻塞模式。

  

或者会尝试等到实际收到nSize字节?

没有

  

如果我理解手册页是正确的,我认为情况并非如此(至少我希望如此)。

正确。

  

或者recv将返回-1并且errno = EAGAIN或EWOULDBLOCK?

是的,如果您处于非阻止模式且没有数据。

  
      
  1. 如果recv以-1返回缓冲区会发生什么?
  2.   

没有

  

在这种情况下它是否始终保持不变

  

或者可能是部分数据已经被放入其中

没有。如果你有任何数据,你会得到它的长度,而不是-1。

  

然后我永远不会知道转移了多少字节,所以我认为情况并非如此,对吧?

右。