我目前正在开发一个 TCP 服务器,并且使用多线程,因此为此我使用 Server.start() 初始化一个服务器,它给我一个类似的 fd,然后我初始化一个无限循环来接受并启动新线程,如下所示:
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 中,我启动了另一个无限循环,通过执行此函数来接收:
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;
}
但是由于我无法解释它在接收时崩溃的原因,我尝试调试它,但我无法解释这件事。
PS:发送效果完美。
std::thread
对象被破坏并且关联的线程仍在运行,则调用 std::terminate
。
这在文档中指定:
如果 *this 有关联的线程 (joinable() == true),则调用 std::terminate()。
在代码的这一部分中:
while (true)
{
int fd = server.loop();
std::thread t(newclient, fd);
}
t
的范围在迭代结束时结束,并且 std::thread
对象很可能仍在运行时被销毁。因此 std::terminate
被调用并且程序退出。
要解决该问题,您应该保留所有
t
,只要它们的关联线程正在运行。例如,您可以将它们存储在您的 Server
类的容器中。