簡體   English   中英

套接字:當客戶端讀取消息時,多線程不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM