2
我正在使用阻塞套接字來接受連接。我很少遇到這個使得調試困難的錯誤。接受返回EAGAIN錯誤。這怎麼可能是一個阻塞套接字?EAGAIN錯誤接受阻塞套接字
我正在使用阻塞套接字來接受連接。我很少遇到這個使得調試困難的錯誤。接受返回EAGAIN錯誤。這怎麼可能是一個阻塞套接字?EAGAIN錯誤接受阻塞套接字
如果套接字已設置接收超時(使用SO_RCVTIMEO
套接字選項),則當超時到期時,accept
將返回EAGAIN
。
該代碼將展示它(也讓你調查提供的信號的影響):
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#define TESTEXIT(s, f) if (s < 0) { perror(f); exit(1); }
void handler(int x)
{
return;
}
int main()
{
int s;
int r;
struct sockaddr_in sin;
socklen_t sin_len = sizeof sin;
struct timeval timeo = { .tv_sec = 5, .tv_usec = 0 };
signal(SIGUSR1, handler);
s = socket(PF_INET, SOCK_STREAM, 0);
TESTEXIT(s, "socket");
r = listen(s, 10);
TESTEXIT(r, "listen");
r = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof timeo);
TESTEXIT(r, "setsockopt");
r = accept(s, (struct sockaddr *)&sin, &sin_len);
TESTEXIT(r, "accept");
return 0;
}
我覺得內核代碼的相關位可以在net /支持IPv4/inet_connection_sock.c可以發現,函數inet_csk_wait_for_connect()。 我不完全清楚在那裏會發生什麼,但它看起來像函數可以返回-EAGAIN,如果等待被信號以外的任何東西中斷(它會返回-EINTR)。 我不知道喚醒的其他原因是否與您提到的接收超時一樣。 – 2009-12-16 22:24:18
@caf我有一個帶'recv'超時的套接字,每次超時都會收到'EAGAIN'錯誤,我是不是應該用'accept'超時,或者只是接收錯誤而忽略它? – razzak 2016-02-16 15:24:38
@razzak:呃,超時的整個意義在於它會導致阻塞調用在超時過期時返回,從而允許程序做出反應並可能做其他一些工作。因此,當程序返回'EAGAIN'時,你的程序要對超時過期做出響應,或者在超時到期時你沒有任何事情要做,請不要設置超時。 – caf 2016-02-17 03:28:04