Errno 35(EAGAIN)接到了recv电话

时间:2013-01-30 01:37:36

标签: c macos sockets

我有一个等待recv的套接字,然后在接收数据后,向前发送数据进行处理。然而,它再次用于recv,这次它没有收到任何返回-1并且当打印出errno时它打印35(这是EAGAIN)。

仅在MAC OS Lion操作系统上发生这种情况,对于其他操作系统,这种情况完全正常

do{
 rc = recv(i, buffer, sizeof(buffer), 0);
 if (rc < 0){
      printf("err code %d", errno); 
 }
 if(rc == 0){ 
      //Code for processing the data in buffer 
      break; 
 } 
      ....
}while(1);

编辑:更正了缩进和错误

2 个答案:

答案 0 :(得分:4)

您可以将套接字设置为非阻塞模式或启用接收超时。这是来自mac上的recv(2)

The calls fail if:
[EAGAIN] The socket is marked non-blocking, and the receive operation would block, or a receive timeout had been set, and the timeout expired before data were received.

编辑0:

嗯,道歉再次引用。这次来自intro(2)

11 EDEADLK Resource deadlock avoided. An attempt was made to lock a system resource that would have resulted in a deadlock situation.
...
35 EAGAIN Resource temporarily unavailable. This is a temporary condition and later calls to the same routine may complete normally.

只需使用strerror(3)找出实际问题。

答案 1 :(得分:1)

您的套接字处于非阻止模式。 EAGAINrecv()(和其他系统调用)的正常返回,当没有可读取的数据时。从这个意义上来说,这不是一个错误。

如果意味着您的套接字是非阻止的,那么您需要对其进行监控,以确定何时有可用数据,并且只有在有可用数据时才调用recv()。使用poll()(或特定于FreeBSD和MacOS的kqueue)进行监控。通常这是在应用程序的主事件循环中完成的。

如果并不意味着您的套接字是非阻止的,那么您应该使用fcntl()将其设置为阻止更多:

flags = fcntl(i, F_GETFL, 0); /* add error checking here, please */
flags &= ~O_NONBLOCK;
fcntl(i, F_SETFL, flags); /* add more error checking here! */

但是你应该知道套接字(和所有文件描述符)的默认阻塞状态是阻塞,所以如果你的套接字处于非阻塞模式,那么这意味着某人或某事已手动使其无阻塞

在阻止模式下,recv调用将阻止并等待更多数据,而不是返回EAGAIN(或EWOULDBLOCK,这与EAGAIN相同。)< / p>