Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using accept() and select() at the same time?

Tags:

I've got an event-driven network server program. This program accepts connections from other processes on other hosts. There may be many short-lived connections from different ports on the same remote IP.

Currently, I've got a while(1) loop which calls accept() and then spawns a thread to process the new connection. Each connection is closed after the message is read. On the remote end, the connection is closed after a message is sent.

I want to eliminate the overhead of setting up and tearing down connections by caching the open socket FDs. On the sender side, this is easy - I just don't close the connections, and keep them around.

On the receiver side, it's a bit harder. I know I can store the FD returned by accept() in a structure and listen for messages across all such sockets using poll() or select(), but I want to simultaneously both listen for new connections via accept() and listen on all the cached connections.

If I use two threads, one on poll() and one on accept(), then when the accept() call returns (a new connection is opened), I have to wake up the other thread waiting on the old set of connections. I know I can do this with a signal and pselect(), but this whole mess seems like way too much work for something so simple.

Is there a call or superior methodology that will let me simultaneously handle new connections being opened and data being sent on old connections?

like image 352
Borealid Avatar asked Aug 09 '10 22:08

Borealid


2 Answers

Last time I checked, you could just listen on a socket and then select or poll to see if a connection came in. If so, accept it; it will not block (but you may want to really should set O_NONBLOCK just to be sure)

like image 195
mvds Avatar answered Sep 22 '22 12:09

mvds


you could use listen then use select or poll then accept

if (listen(socket_fd, Number_connection) < 0 ) {     perror("listen");     return 1; } fd_set set; struct timeval timeout; int rv; FD_ZERO(&set); /* clear the set */ FD_SET(socket_fd, &set); /* add our file descriptor to the set */  timeout.tv_sec = 20; timeout.tv_usec = 0;  rv = select(socket_fd + 1, &set, NULL, NULL, &timeout); if (rv == -1) {     perror("select"); /* an error occurred */     return 1; } else if (rv == 0) {     printf("timeout occurred (20 second) \n"); /* a timeout occurred */     return 1; } else {     client_socket_fd = accept (socket_fd,(struct sockaddr *) &client_name, &client_name_len); } 
like image 29
Khaled Avatar answered Sep 23 '22 12:09

Khaled