2016-09-18 35 views
2

我有一個服務器,它可以接受兩個套接字連接。它爲每個套接字創建一個線程,以便可以並行發送消息。
套接字:多線程在客戶端讀取消息時不工作

現在我試圖編寫我的客戶端。

我創建了一個名爲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,這意味着現在客戶端只是一個簡單的線程,它不會收到任何東西,事情會很好----我可以得到兩個線程的兩個ID。

爲什麼?

編輯 看來我錯誤地使用了join
我需要的是main不會執行//something else,直到兩個線程一起獲得1000個字符。
我該怎麼辦?

+0

我很難理解你的問題,但'read()'call默認是阻塞的。 –

+0

@AbhinavGauniyal當我執行客戶端時,'main'會在'td0.join()'處阻塞。爲什麼。 – Yves

+0

,因爲'join()'被阻塞。 'join()'在線程結束時返回。你想要做什麼? – shrike

回答

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)確保輸入數據正確地附加在緩衝區的正確位置。

相關問題