Hello everyone,
I'm developing a multi-client server on Linux and I've noticed a strange behavior: I'm using a regular Makefile to compile and run my server, nothing fancy. But now I've tried to run my server by hand using the command line and my server won't accept any incoming connections ! In other word: there isn't any problem problem when I launch it from "make run" and there is one only If I do "./build/debug/main" (see the Makefile).
A little description of my program is required to understand where the problem could be. It is made of a main thread which creates an Server instance and the socket of the server. Then it creates a pthread (listening thread) with the passed server socket fd. It should share the same socket (same integer value) as in the main thread.
The goal of the main thread is to wait for some data on any socket (via epoll_wait). The goal of the listening thread is to accept any incoming connections, to queue it in epoll for the main then wait again.
I tested to copy the code of the listening thread in the main one (for this test I removed the pthread_create of course) and it was working without any error.
The error happens (when launching by hand) in the listening thread when it accepts on the main socket because it returns -1.
So it seems that the pthread doesn't share the main thread socket _only_ when it is ran by hand ! What does the Makefile and how could it modify the behavior of sockets with pthread ?! I need some help because I don't have any clue about this behavior.
Makefile : http://pastebin.com/QFerjewd (posted outside not to overload the topic)
Main thread :
int i = 1;
// Init a socket
_socket = socket(family, type, protocol); // it's: AF_INET, SOCK_STREAM, 0
if (_socket < 0)
Globals::Log(LOGGER_TYPE_FATAL, LOGGER_CAT_NETWORK, true, "ERROR opening socket");
// Server socket struct
bzero((char *) &_serv_addr, sizeof(_serv_addr));
_serv_addr.sin_family = AF_INET;
_serv_addr.sin_addr.s_addr = INADDR_ANY;
_serv_addr.sin_port = htons(port); // it's: 2055
memset(&_serv_addr.sin_zero, 0, 8); // zero the rest
setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
// Epoll
_epoll_clients = epoll_create(SERVER_MAX_CLIENTS);
if (_epoll_clients < 0)
Globals::Log(LOGGER_TYPE_FATAL, LOGGER_CAT_NETWORK, true, "ERROR while creating epoll");
// Create the listener
_listener = new SocketServerListener(this, _socket); // Give the socket to the listening thread (it's a integer !)
if (bind(_socket, (struct sockaddr *) &_serv_addr, sizeof(_serv_addr)) < 0)
Globals::Log(LOGGER_TYPE_FATAL, LOGGER_CAT_NETWORK, true, "ERROR on binding");
listen(_socket, SERVER_QUEUE_MAX);
_listener->Start(NULL); // <-- pthread_create (Listening Thread -> code below)
OnStart();
WaitEpoll();
Listening Thread:
while (Continue()) {
int socket;
struct sockaddr_in addr;
socklen_t len;
#ifdef DEBUG
Globals::Log(LOGGER_TYPE_DEBUG, LOGGER_CAT_NETWORK, false, "[SSL Thread]: Waiting for clients.");
#endif
/* always returns -1 when launching by hand
* so the error below is printed out and client is disconnected
*/
socket = accept(_socket, (struct sockaddr *) &addr, &len);
if (socket < 0) {
Globals::Log(LOGGER_TYPE_ERROR, LOGGER_CAT_NETWORK, false, "[SSL Thread]: Invalid socket %i (%s)",
socket, strerror(errno));
continue;
}
#ifdef DEBUG
Globals::Log(LOGGER_TYPE_DEBUG, LOGGER_CAT_NETWORK, false, "[SSL Thread]: Accepted a new client on %i", socket);
#endif
// Send to the parent
_parent->OnConnect(socket);
}