I have a problem with a server socket under Linux. For some reason, the server socket unknown to me goes to zero, and I get a Bad file descriptor error in a select call that is waiting for an incoming connection. This problem always occurs when I close an unconnected socket connection in another thread. This happens on embedded Linux with the 2.6.36 kernel.
Does anyone know why this will happen? Is it normal that the server socket might just disappear, resulting in a Bad file descriptor ?
change Another socket code implements a VNC server and works in a completely different thread. The only thing that is especially important in this other code is the use of setjmp/longjmp , but this should not be a problem.
The code that creates the server socket is as follows:
int server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(1234); const int optionval = 1; setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optionval, sizeof(optionval)); if (bind(server_socket, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("bind"); return 0; } if (listen(server_socket, 1) < 0) { perror("listen"); return 0; }
I am waiting for an incoming connection using the following code:
static int WaitForConnection(int server_socket, struct timeval *timeout) { fd_set read_fds; FD_ZERO(&read_fds); int max_sd = server_socket; FD_SET(server_socket, &read_fds); // This select will result in 'EBADFD' in the error case. // Even though the server socket was not closed with 'close'. int res = select(max_sd + 1, &read_fds, NULL, NULL, timeout); if (res > 0) { struct sockaddr_in caddr; socklen_t clen = sizeof(caddr); return accept(server_socket, (struct sockaddr *) &caddr, &clen); } return -1; }
edit When a problem occurs, I am currently just restarting the server, but I donβt understand why the server identifier should suddenly become an invalid file descriptor:
int error = 0; socklen_t len = sizeof (error); int retval = getsockopt (server_socket, SOL_SOCKET, SO_ERROR, &error, &len ); if (retval < 0) { close(server_socket); goto server_start; }