套接字:客户端读取消息时多线程不起作用
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))) > 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, &recvBuff[total], sizeof(Data) - total)
确保传入数据正确附加到缓冲区中的正确位置。
【讨论】:
以上是关于套接字:客户端读取消息时多线程不起作用的主要内容,如果未能解决你的问题,请参考以下文章