7

我有一个等待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);

编辑:更正缩进和 errno

4

2 回答 2

7

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

如果出现以下情况,调用将失败:

[EAGAIN]套接字被标记为非阻塞,接收操作会阻塞,或者设置了接收超时,在接收到数据之前超时。

编辑0:

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

11 EDEADLK避免了资源死锁。试图锁定可能导致死锁情况的系统资源。

...

35 EAGAIN资源暂时不可用。这是一种临时情况,以后对同一例程的调用可能会正常完成。

只是strerror(3)用来找出实际问题。

于 2013-01-30T02:39:33.393 回答
3

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

如果您打算让您的套接字是非阻塞的,那么您需要监视它以找出它何时有数据可用,并且只有recv()在有数据可用时才调用。使用poll()(或 kqueue,这是特定于 FreeBSD 和 MacOS)来监控的。通常这是在应用程序的主事件循环中完成的。

如果您的意思不是让您的套接字是非阻塞的,那么您应该将其设置为阻塞更多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)。

于 2013-01-30T02:36:08.707 回答