套接字:客户端读取消息时多线程不起作用

Posted

技术标签:

【中文标题】套接字:客户端读取消息时多线程不起作用【英文标题】:socket: multithreading doesn't work when client reads messages 【发布时间】:2016-09-18 22:02:34 【问题描述】:

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

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

我创建了一个名为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 td0sts[0].run();
std::thread td1sts[1].run();
td0.join(); // stop here
td1.join();
// something else

当我执行程序时,它会阻塞在td0.join();,这意味着我可以在控制台上获取线程td0 的ID,而我永远无法获取其他线程。

但是,当我删除(n = read(sockfd, recvBuff, sizeof(Data))) &gt; 0 时,这意味着现在客户端只是一个简单的线程,它不会收到任何东西,一切都会好起来的----我可以获得两个线程的两个ID。

为什么?

编辑 看来我用错了join。 我需要的是 main 在两个线程一起获得 1000 个字符之前不会执行 //something else。 我该怎么办?

【问题讨论】:

我很难理解你的问题,但read() 电话默认是阻塞电话。 @AbhinavGauniyal 当我执行客户端时,main 将阻塞在td0.join()。为什么。 因为join() 正在阻塞。 join() 在线程结束时返回。你到底想做什么? 你的话题还没有完成。 join() 将在您的线程完成执行时返回。如果这就是你的全部代码,我怀疑read() 还没有返回? @AbhinavGauniyal 我需要的是两个线程并行执行。这两个线程并行执行,直到它们收到 1000 个字符。所以我不应该使用join 【参考方案1】:

您没有错误地使用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, &amp;recvBuff[total], sizeof(Data) - total) 确保传入数据正确附加到缓冲区中的正确位置。

【讨论】:

以上是关于套接字:客户端读取消息时多线程不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在 for 循环中创建的线程不起作用 [重复]

向所有客户端发出的 SocketIO 不起作用

AsyncTask和套接字在android java中不起作用

Boost套接字读取功能不起作用

Posix消息队列接收/发送/打开不起作用?

Web Socket 客户端在 Tomcat 中不起作用