Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
socket编程-recv()函数_C_Sockets - Fatal编程技术网

socket编程-recv()函数

socket编程-recv()函数,c,sockets,C,Sockets,我在unix下的非阻塞套接字c语言中遇到recv函数问题 我已使用以下codeserver程序将套接字设置为非阻塞: int x; x=fcntl(listen_sd,F_GETFL,0); fcntl(listen_sd,F_SETFL,x | O_NONBLOCK); 当我调用recv时,如果消息可用,它将返回消息的长度,如果不可用,它将阻止 我在代码中也使用了select函数 while(1) { /***************************

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

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根本不会返回EWoldblock错误!!
为什么?

我猜您正在将O_非阻塞调用放入用于侦听的套接字中。但是一旦你调用了accept,你就会得到另一个表示连接的套接字。根据平台的不同,这个新套接字可能有也可能没有从另一个套接字继承的O_NONBLOCK

引用从我的linux接受的人:

在Linux上,accept返回的新套接字不会从侦听套接字继承文件状态标志,例如O_NONBLOCK和O_ASYNC。此行为不同于规范的BSD套接字实现。可移植程序不应依赖于文件状态标志的继承性或非继承性,而应始终在从accept返回的套接字上显式设置所有必需的标志


我猜您正在将O_非阻塞调用放入用于侦听的套接字中。但是一旦你调用了accept,你就会得到另一个表示连接的套接字。根据平台的不同,这个新套接字可能有也可能没有从另一个套接字继承的O_NONBLOCK

引用从我的linux接受的人:

在Linux上,accept返回的新套接字不会从侦听套接字继承文件状态标志,例如O_NONBLOCK和O_ASYNC。此行为不同于规范的BSD套接字实现。可移植程序不应依赖于文件状态标志的继承性或非继承性,而应始终在从accept返回的套接字上显式设置所有必需的标志


谢谢。那么你的意思是我必须为accept返回的每个套接字打电话给fcntl?是的,就是这样。或者,如果您使用的是linux,您可以调用GNU特定的accept4函数,该函数接收一个附加参数并为您执行此操作。您的猜测是正确的。我为每个连接及其工作方式调用fcntl。谢谢much@mojtabayazdani-如果您对答案感到满意,请不要忘记将其标记为已接受!谢谢。那么你的意思是我必须为accept返回的每个套接字打电话给fcntl?是的,就是这样。或者,如果您使用的是linux,您可以调用GNU特定的accept4函数,该函数接收一个附加参数并为您执行此操作。您的猜测是正确的。我为每个连接及其工作方式调用fcntl。谢谢much@mojtabayazdani-如果您对答案感到满意,请不要忘记将其标记为已接受!