所以我只是使用 winsock2 和 TCP 编写了一个简单的多线程客户端服务器应用程序。
以下是其工作原理的简要总结:
服务器主线程处于无限循环中接受客户端,然后将它们添加到服务器 vector 中,该 vector 包含每个连接的客户端,如下所示: (只为我的问题添加重要的内容)
std::vector <Client*> clients;
while (true){
clients.push_back(&Client(accept(serverSocket, NULL, NULL), this));
}
当一个新的客户端连接到服务器时,我们基本上会创建一个新的客户端对象,并将新客户端的套接字和服务器本身作为参数。
当时我的想法是为每个客户端提供自己的线程,以便每个客户端都可以同时发送数据。
std::thread tickThread;
Client::Client(SOCKET socket,Server* server) :
isConnected(true),
socket(socket),
server(server)
{
tickThread = std::thread(&Client::tick,this);
}
客户端的线程然后检查客户端是否发送了一些东西,然后将它发送到服务器。它还检查客户端是否仍然连接。 void Client::tick(){
while (isConnected){
errorHandler = recv(socket, receivedData, 255, 0);
if (errorHandler == SOCKET_ERROR){
disconnect();
}
else {
//send received data to server
}
}
如果客户端断开连接,它会告诉服务器从已连接的客户端 vector 中删除客户端,然后将“isConnected” bool 值设置为 false,以便线程可以退出其功能。
void Client::disconnect(){
isConnected = false;
server->removeClient(this);
}
这是它应该如何工作的,但是一旦客户端再次断开连接,服务器就会崩溃并出现错误:
R6010 - 已调用 abort()
所有调试都显示这是我的错误:
switch (_CrtDbgReportW(_CRT_ERROR, NULL, 0, NULL, L"%s", error_text)){
case 1: _CrtDbgBreak(); msgshown = 1; break;
case 0: msgshown = 1; break;
}
所以是的,我真的不知道是什么导致了这次崩溃,但我怀疑它可能与使用客户端功能的线程有关,该线程基本上被删除,因为它正在从服务器的客户端 vector 中删除。
如果这确实是问题所在,你们能给我一些想法,让我更好地实现每个客户端都有自己的线程吗?
编辑:更改了 vector 错误,但是一旦客户端断开连接,崩溃仍然会发生
最佳答案
错误在这段代码中:
while (true){
clients.push_back(&Client(accept(serverSocket, NULL, NULL), this));
}
Client(accept(serverSocket, NULL, NULL), this)
是一个生成临时 Client
的表达式语句完成执行时销毁的对象。但是,您获取该临时对象的地址并将其添加到您的 vector
.
如果你想创建Client
对象并存储指向它们的指针,您将需要为它们分配内存。我建议使用 std::unique_ptr
管理它们,以便您的 vector
声称拥有它们的内存并在它们从 vector
中删除时自动释放它们或 vector
本身被摧毁。然后你的代码变成:
std::vector<std::unique_ptr<Client>> clients;
while (true){
clients.push_back(std::make_unique<Client>(accept(serverSocket, NULL, NULL), this));
}
关于c++ - 一旦客户端断开连接,服务器应用程序就会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32702647/