2017-10-18 60 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[],这在发送时工作正常。