socket编程-recv()函数
我在unix下的非阻塞套接字c语言中遇到recv函数问题 我已使用以下codeserver程序将套接字设置为非阻塞: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) { /***************************
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-如果您对答案感到满意,请不要忘记将其标记为已接受!