socket编程-recv()函数

时间:2012-03-16 10:01:29

标签: c sockets

我在非阻塞套接字(unix下的c语言)中遇到recv()函数的问题 我已使用以下代码(服务器程序)将套接字设置为非阻塞:

int x;
x=fcntl(listen_sd,F_GETFL,0);
fcntl(listen_sd,F_SETFL,x | O_NONBLOCK);

当我呼叫recv()时,如果消息可用,则返回消息的长度,如果不是则阻止!!

我也在我的代码中起诉了select函数。

while(1)
       {
          /**********************************************/
          /* Receive data on this connection until the  */
          /* recv fails with EWOULDBLOCK.  If any other */
          /* failure occurs, we will close the          */
          /* connection.                                */
          /**********************************************/
          rc = recv(i, buffer, sizeof(buffer), 0);
          if (rc < 0)
          {
         if(errno == EAGAIN||errno == EWOULDBLOCK)
         {
        printf("no message\n");
        break;
         }

                perror(" recv() failed");
                close_conn = TRUE;

          }

          /**********************************************/
          /* Check to see if the connection has been    */
          /* closed by the client                       */
          /**********************************************/
          if (rc == 0)
          {
             printf("connection closed\n");
             close_conn = TRUE;
             break;


          }

          /**********************************************/
          /* Data was recevied                          */
          /**********************************************/
          len = rc;
          printf("  %d bytes received\n", len);
        }

如果客户端发送消息并且没有关闭连接,则第一次调用recv()时服务器获取消息并且第二次调用被阻止(换句话说,recv()根本不会返回EWOULDBLOCK错误!!) 为什么?

1 个答案:

答案 0 :(得分:3)

我的猜测是你将O_NONBLOCK调用放入用于listen的套接字中。但是一旦你调用了accept,你就会得到代表连接的另一个套接字。这个新套接字可能有也可能没有从另一个套接字继承的O_NONBLOCK,具体取决于平台。

引用我的linux中的man accept

  

在Linux上,accept()返回的新套接字不会从侦听套接字继承文件状态标志,例如O_NONBLOCKO_ASYNC。此行为与规范BSD套接字实现不同。便携式程序不应依赖继承或不继承文件状态标志,始终在accept()返回的套接字上显式设置所有必需的标志