im just started coding in c++ and i am trying to build a multithreaded server but i got some errors. first, here is the code i got:
while(true){
printf("waiting for a connection\n");
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (sockaddr*)&sadr, &addr_size))!= -1)
{
printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
//std::thread th(&Network::SocketHandler, NULL);
std::thread th(Network::SocketHandler, (void*)csock);
th.detach();
}
else
{
fprintf(stderr, "Error accepting %d\n", errno);
}
}
}
void Network::SocketHandler(void* lp)
{
int *csock = (int*)lp;
char buffer[1024];
int buffer_len = 1024;
int bytecount;
memset(buffer, 0, buffer_len);
if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
}
printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
strcat(buffer, " SERVER ECHO");
if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
fprintf(stderr, "Error sending data %d\n", errno);
}
printf("Sent bytes %d\n", bytecount);
}
i am getting a error when compiling at this line:
std::thread th(Network::SocketHandler, (void*)csock);
saying:
std::thread::thread(_Callable&&, _Args&& …) [with _Callable = void (Network::)(int); _Args = {void*}]
no known conversion for argument 1 from ‘’ to ‘void (Network::&&)(int)’
how can i fix this? or is there a better way to create a multithreaded server any examples maybe of other posts?
Why are you passing in a
void *instead of anint *when it’s clear that what you really want is anint *?Just change the function signature to:
and remove the cast in the code that does the calling:
Now, you will still get an error, and it will be for a different reason.
Network::SocketHandleris a member function. It needs athispointer. Normally you would call such functions with syntax likeobject.SocketHandler(csock)orobjptr->SocketHandler(csock). When you call it that way with::std::threadyou aren’t giving it an object to be called on. It has nothispointer.What you should do is change the function signature again to:
and then your code will work just fine. It doesn’t look like the function makes use of any member variables, so it doesn’t need a
thispointer.On a different note, it looks like you’re trying to adapt something originally written for pthreads. If I were doing this for the C++11 thread library I would do it in a rather different manner.
I can’t see your entire program, so I don’t really have the luxury of re-designing it. But, from what I can see, I would make these tweaks:
The changes are fairly subtle. The C++11 thread library lets you call functions and provide all their arguments, and it handles this in a thread-safe way. There is no need to pass
void *anymore, nor is there a need to usemallocornewto create storage space for those arguments you can just pass the arguments your thread needs directly to the thread constructor.Your program, in fact, has a memory leak. It never reclaims the space it
mallocs forcsockto point to. If it ran for a long time, it would eventually run out of memory as the space for all those filehandles was never reclaimed.Your program may also have a filehandle leak. You do not appear to
closethe socket inNetwork::SocketHandler. But since I don’t have visibility on your entire program, I can’t be sure about that.