I'm currently developing a TCP server and I use multi threading, so for this I init a server using a Server.start()
which give me a fd
like and then I init an infinite loop to accept and start new thread like this:
int main()
{
spdlog::set_pattern("[%H:%M:%S %z] [%^---%L---%$] [thread %t] %v");
Server server(9001);
int sockfd = server.start();
if (sockfd < 0)
{
spdlog::error("Cannot init server");
return 1;
}
while (true)
{
int fd = server.loop();
std::thread t(newclient, fd);
}
}
void newclient(int fd)
{
Handler handler;
handler.loop(fd);
closesocket(fd);
};
handler.loop:
void Handler::loop(int fd){
std::string buffer;
Communication communication(fd);
while(true){
buffer.erase();
buffer = communication.recv_str();
if (buffer == "") {
continue;
}
}
...
}
and communication.recv_str()
:
std::string Communication::recv_str(){
std::vector<char> buffer(CHUNK_SIZE);
std::string rcv;
long bytes_received = 0;
do {
bytes_received = recv(fd, &buffer[0], CHUNK_SIZE, 0);
if ( bytes_received < 0 ) {
std::cout << "recv failed, err: " << WSAGetLastError() << std::endl;
} else if ( bytes_received == 0 ) {
return "";
} else {
rcv.append(buffer.cbegin(), buffer.cend());
}
} while( bytes_received == CHUNK_SIZE );
return rcv;
}
so if I compile and run this when I try to connect to the server I got this message:
But for a reason which I cannot explain it's crashing at the recv
, I've tried to debug it but I cannot explain this thing. No message errors or others indications, I do not understand.
PS: sending works perfectly.
If a std::thread
object is destructed and the associated thread is still running, std::terminate
is called.
This is specified in the documentation:
If
*this
has an associated thread (joinable() == true
),std::terminate()
is called.
In this part of your code:
while (true)
{
int fd = server.loop();
std::thread t(newclient, fd);
}
t
's scope is ending at the end of the current iteration and the std::thread
object is destroyed while it is most likely still running. Therefore std::terminate
is called and the program exits.
To solve the problem, you should keep all your std::thread
objects as long as their associated thread is running. You could, for example, store them in a container in your Server
class.