2017-10-18 159 views
-2

我有一個UDP客戶端以指定的速率向服務器發送消息。費率需要保持不變,所以我決定嘗試在單獨的線索中收到回覆,以避免阻止或延遲recvfrom()。在收到信息之前是否可以「等待」完整信息?要做到這一點,最好的策略是什麼?Recvfrom:等待完整的消息(可變大小的消息,線程)

while (true) 
{ 
    //std::this_thread::sleep_for(std::chrono::milliseconds(5000)); 
    if (recvfrom(threadSock, ReceiveBuf, BufLength, 0, 0, 0) == SOCKET_ERROR) 
    { 
     printf("Thread Receive failed with error %ld\n", GetLastError()); 
     break; 
    } 
    else 
    { 
     printf("Reply received: %s\n\n", ReceiveBuf); 
    } 
    memset(ReceiveBuf, '\0', BufLength); 
} 

上面是我的接收代碼。目前,只有回覆的前8個字符被讀入緩衝區(緩衝區是512字節)。

如何等待完整的消息(記住消息長度是可變的)。

這甚至可能嗎?也許有更好的方法。

在此先感謝。

編輯:我應該澄清的打印僅用於測試。他們不會在最終的結果,因爲從線程打印給出奇怪的內聯打印。

+1

你怎麼知道你只有8個字節?您不評估收到的字節數。 – 2017-10-18 09:48:43

+0

斷點:)這一切都是WIP –

+1

這不太可能只有8個字節,如果發送更多iif。 – 2017-10-18 09:52:36

回答

0

根據MSDN

recvfrom函數接收一個數據報,並且存儲的源地址。

對於面向消息的套接字,將從第一個入隊消息中提取數據,直到指定的緩衝區的大小。如果數據報或消息大於指定的緩衝區,則緩衝區將填充數據報的第一部分,並且recvfrom將生成錯誤WSAEMSGSIZE。對於不可靠的協議(例如UDP),多餘的數據會丟失。對於UDP,如果接收到的數據包不包含數據(空),則recvfrom函數函數的返回值爲零。

因此,您不能接收傳入消息的一部分,只有當操作系統可以處理並返回入隊數據報時,接收纔會返回。

+0

完全沒有必要。 UDP保留消息邊界。 – EJP

+0

@EJP,我誤解了OP的問題,我雖然想要多個消息緩衝。我更新了答案。 –

+0

感謝@DanielTrugman。似乎我沒有記住UDP數據包是作爲整體發送的,並沒有考慮到我的服務器根本沒有發送整個數據的可能性。 –

0

在完整性的利益,而小的機會任何人相似困惑的痛苦發現這一點,解決方案如下:

是的,這是一個愚蠢的問題,我應該已經意識到recvfrom的等待一個完整的數據報。問題出在我的服務器上。

這是一個服務器沒有發送完整數據的問題。我不知道確切的原因,但爲了解決這個問題,我將char*轉換成了我的回覆存儲到(並正確打印)到char[],這在發送時工作正常。