Bar*_*uda 3 c sockets linux error-handling
如accept()手册页RETURN VALUE部分所述:
错误处理
Linuxaccept()(和accept4())将新套接字上已经挂起的网络错误作为错误代码从accept(). 此行为不同于其他 BSD 套接字实现。为了可靠运行,应用程序应该检测为协议定义的网络错误,accept()并EAGAIN通过重试来处理它们。在TCP / IP的情况下,这些都是ENETDOWN,EPROTO,ENOPROTOOPT,EHOSTDOWN,ENONET,EHOSTUNREACH,EOPNOTSUPP,和ENETUNREACH。
这是否意味着必须errno在accept()返回之后和检查 的返回值之前检查 的值accept()?如果是,如果errno设置,必须采取哪些步骤?
这是我的代码处理片段accept():
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if((errno == ENETDOWN || errno == EPROTO || errno == ENOPROTOOPT || errno == EHOSTDOWN ||
errno == ENONET || errno == EHOSTUNREACH || errno == EOPNOTSUPP || errno == ENETUNREACH))
return;
if (newsockfd < 0)
{
// error
}
else if(newsockfd > 0)
{
// accepted a new connection
}
else
{
// blah blah blah
}
Run Code Online (Sandbox Code Playgroud)
我得出的结论是,在这种情况下,您可以稍后再试一次。我的结论正确吗?
首先,您检查accept()返回值。如果accept()返回值小于0,则应检查errno。如果是ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, 或ENETUNREACH,那么您可以accept()再次调用。否则发生了一些不好的事情,你应该停止调用accept()(例如,你已经将错误的 listen socket 作为accept()参数传递了)。
这就是我对代码的理解。
以下是错误处理的完成方式:
while (running) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
// error
perror ("accept");
if((errno == ENETDOWN || errno == EPROTO || errno == ENOPROTOOPT || errno == EHOSTDOWN ||
errno == ENONET || errno == EHOSTUNREACH || errno == EOPNOTSUPP || errno == ENETUNREACH)) {
continue;
}
exit (EXIT_FAILURE);
}
// accepted a new connection
// blah blah blah
}
Run Code Online (Sandbox Code Playgroud)