[英]C : non blocking sockets with timeout : how to avoid busy waiting?
The following code allows for a server to wait for a client to connect to a (already binded) socket. 以下代码允许服务器等待客户端连接到(已绑定)套接字。 It terminates either when a client connects to the socket, or when "server_run" takes the value 0: this allows other part of the code to shutdown the server when suitable to do so.
当客户端连接到套接字或“ server_run”值为0时,它终止:这允许代码的其他部分在适当的时候关闭服务器。
static inline int wait_for_client_to_connect(int sockfd, int* server_run){
int client_found = 0;
int clientfd = 0;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
if ( listen(sockfd,1) != 0 ) return -1;
while ( client_found==0 && *server_run==1 ) {
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);
if ( clientfd < 0 ) {
clientfd = 0;
if (errno==EAGAIN || errno==EWOULDBLOCK) usleep(10); // nobody connected, wait for request
else return -1; // something wrong, send error
} else { // client found, configuring socket and exit
client_found=1;
int nodelay_flag = 1;
setsockopt(clientfd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay_flag, sizeof(int)); // disable nagle algorithm
}
}
return clientfd;
}
According to answer and comments to another posts ( C : non blocking sockets with timeout : how to check if connection request was made? ), this is not the way to go because it involves busy waiting. 根据对另一篇文章的回答和评论( C:具有超时的非阻塞套接字:如何检查是否发出连接请求? ),这不是可行的方法,因为它涉及繁忙的等待。
Eg a comment says : 例如,评论说:
"The standard way to handle shutdown with blocking IO is to use a signal handler to set a shutdown flag and then check the flag when listen returns -1 with errno set to EINTR"
“使用阻塞的IO处理关机的标准方法是使用信号处理程序设置关机标志,然后在errno设置为EINTR的侦听返回-1时检查该标志”
It is very unclear to me how the code above could be adapted to "use a signal handler" .... 对我来说还不清楚如何将上面的代码修改为“使用信号处理程序”...。
You want to select()
on the socket, and only do an accept
if it is ready for reading. 您想在套接字上
select()
,并且只有在准备好读取时才执行accept
。 select()
has a timeout, so you can wait either forever, or perhaps better for a second or two in each loop, as select
will exit immediately if an FD is ready (here 'ready to read' means 'ready to accept'). select()
有一个超时,因此您可以永久等待,或者在每个循环中等待一到两秒钟,因为如果FD准备就绪, select
将立即退出(此处“ ready to read”表示“ ready to accept”) 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.