我在非并发单进程实现中有一个带有 TCP 套接字的服务器。
int main(int argc, char** argv) {
int sock_ds, acc_sock_ds, opt, client_addr_l;
unsigned short port;
struct sockaddr_in server_addr, client_addr;
/*Parsing command line: port-number retrieving*/
/*...*/
printf("Port number retrieved (%d), server is starting ...\n", port);
/*TCP Socket creation*/
sock_ds = socket(AF_INET, SOCK_STREAM, 0);
if(sock_ds == -1){
fprintf(stderr, "Socket creation error\n");
exit(EXIT_FAILURE);
}
/*Server address binding*/
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
//use setsockopt(2) with OS_REUSEADR ???
if(bind(sock_ds, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1){
fprintf(stderr, "Address binding error\n");
exit(EXIT_FAILURE);
}
/*Server with passive socket*/
if(listen(sock_ds, SOMAXCONN) == -1){
fprintf(stderr, "Listen call error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("Server is ready. Waiting for connections.\n");
/*Busy-waiting server*/
while(1){
memset(&client_addr, 0, sizeof(client_addr));
acc_sock_ds = accept(sock_ds, &client_addr, &client_addr_l);
/*Connect error management*/
if(acc_sock_ds == -1){
errsv = errno;
if(errsv == 12 || errsv == 23 ){
/*Fatal errors ENOMEM, ENFILE*/
fprintf(stderr, "Fatal error on accept\n");
exit(EXIT_FAILURE);
}
else if(errsv == 103 || errsv == 4 || errsv == 71 || errsv == 92
|| errsv == 112 || errsv == 113 || errsv == 95 || errsv == 101)
/*ECONNABORTED, EINTR, EPROTO, ENOPROTOOPT,
* EHOSTDOWN, EHOSTUNREACH, EOPNOTSUPP, ENETUNREACH*/
continue;
else if(errsv == 100 || errsv == 64){
/* ENETDOWN - ENONET */
/*start timeout...*/
continue;
}
}
}
}
在这个测试中,我预计服务器也会accept(2)
在失败时继续进行调用。我知道有一些终端错误情况,例如EBADF
. 我是否应该根据 的值提供不同的行为(过程终止)errno
?对于哪些值,服务器必须停止,哪些可以继续等待?
代码已编辑。我从来没有通过errno进行错误处理。如果有错误或建议,请通知他们。我注意到这两个条件ENETDOWN
-ENONET
是由缺乏网络暗示的。对于这些情况,我是否应该期望超时以防止停滞?