socket:当客户端读取消息时,多线程不起作用

时间:2016-09-18 22:02:34

标签: c++ multithreading sockets

我有一台服务器,可以接受两个套接字连接。它为每个套接字创建一个线程,以便可以并行发送消息。

现在我正在尝试为我的客户编码。

我创建了一个名为SocketThread的类作为套接字的线程。这是主要代码:

void SocketThread::ReadData()
{
    int n = 0;
    while (!finished)
    {
        while ((n = read(sockfd, recvBuff, sizeof(Data))) > 0)
        {
            std::cout<<std::this_thread::get_id()<<std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(2000));
        }
    }
}

std::thread SocketThread::run()
{
    return std::thread([=] { ReadData(); });
}
函数main中的


SocketThread s0("127.0.0.1", 10000);
SocketThread s1("127.0.0.1", 10000);
std::thread td0{sts[0].run()};
std::thread td1{sts[1].run()};
td0.join(); // stop here
td1.join();
// something else

当我执行程序时,它将在td0.join();处阻塞,这意味着我可以在控制台上获取线程td0的id,而我永远不会得到另一个线程。

然而,当我删除(n = read(sockfd, recvBuff, sizeof(Data))) > 0时,这意味着现在客户端只是一个简单的线程,它不会收到任何东西,事情会好起来的 - 我可以得到两个中的两个线程。

为什么?

修改 我似乎错误地使用了join 我需要的是main在两个线程一起获得1000个字符之前不会执行//something else 我该怎么办?

1 个答案:

答案 0 :(得分:0)

您未正确使用join()。如果您希望阻塞main()直到两个线程都结束,那么您的代码是正确的:td0.join()将阻塞,直到线程td0结束,td1相同。

现在,如果您希望线程在收到sizeof(Data)个字节后结束,那么您的函数void SocketThread::ReadData()应该如下所示:

void SocketThread::ReadData()
{
    int n, total = 0;
    while (!finished)
    {
        while ((n = read(sockfd, &recvBuff[total], sizeof(Data) - total)) > 0)
        {
            total += n;
        }
        if (n == -1)
        {
            // manage error here
        }
        if (n == 0)
        {
            std::cout << "client shut the socket down; got " << total << " bytes over " << sizeof(Data) << std::endl;
            finished = true;
        }
    }
}

简短说明:无法保证您可以在一次read()操作中获取客户端发送的所有数据,因此您需要调用read()并将数据累积到缓冲区中,直到获得返回值0(表示客户端关闭套接字)。 read(sockfd, &recvBuff[total], sizeof(Data) - total)确保将接收数据正确附加到缓冲区中的正确位置。