recv 在线程中不起作用 - Windows c++

问题描述 投票:0回答:1

我目前正在开发一个 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:发送效果完美。

c++ windows sockets winsock2
1个回答
0
投票

如果

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
类的容器中。

© www.soinside.com 2019 - 2024. All rights reserved.