[英]socket: multithreading doesn't work when client reads messages
我有一台服務器,可以接受兩個套接字連接。 它為每個套接字創建一個線程,以便可以並行發送消息。
現在,我正在嘗試編碼我的客戶端。
我創建一個名為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.join();
,這意味着我可以在控制台上獲取線程td0
的ID,而從不獲取其他線程。
但是,當我刪除(n = read(sockfd, recvBuff, sizeof(Data))) > 0
,這意味着現在客戶端只是一個簡單的線程,它不會接收任何東西,一切都會好起來- -我可以得到兩個線程的兩個ID。
為什么?
編輯看來我以前join
不正確。
我需要的是main
直到兩個線程一起獲得1000個字符后才執行//something else
。
我該怎么辦?
您沒有錯誤地使用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)
確保傳入的數據正確地附加在緩沖區的正確位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.