I'm developing an application which involves 1 client and 1 server.
I want the server to listen for only 5 seconds for a connection. If the client is not attempting to establish a connection then the sever should stop listening and return an error message. If the client attempts to establish a connection then the server should accept the connection.
The server is listening forever if the client is not making an attempt to establish a connection. I want the server to listen for only 5 seconds, how can this be achieved?
This is the server-side output - server is waiting for client forever:
void reception(){
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
else
printf("Server listening..\n");
len = sizeof(cli);
connfd = accept(sockfd, (SA*)&cli, &len);
/*
Some function should be added at this point to
stop the server from listening after 5 seconds
*/
if (connfd < 0) {
printf("server acccept failed...\n");
exit(0);
}
else
printf("server acccept the client...\n");
receive(connfd);
close(sockfd);
}
You are using the listening socket in blocking mode, so
accept()
will block the calling thread until a client connects. To use a timeout, callselect()
or(e)poll()
first to wait for the listening socket to enter a readable state indicating a connection is pending BEFORE you then callaccept()
.For example:
Either way, note that there is a very small race condition created by these scenarios. If the client connects and then disconnects before
accept()
is called,accept()
may block waiting for a new pending connection, or it may return a valid file descriptor that fails on subsequent I/O calls. There is no guarantee one way or the other.To solve the race condition, you can either:
put the listening socket into non-blocking mode. If
select()
reports the listening socket has a pending connection, butaccept()
is not able to accept it right away, then you can act accordingly.use
accept()
on a listening socket in blocking mode, as you originally were, but usealert()
to scheduleaccept()
to be interrupted if it doesn't exit before 5 seconds have elapsed. See this answer for an example.