recv() 接收部分消息的套接字编程问题
Posted
技术标签:
【中文标题】recv() 接收部分消息的套接字编程问题【英文标题】:Socket programming issue with recv() receiving partial messages 【发布时间】:2012-04-20 17:18:01 【问题描述】:我有一个正在接收流式股票报价数据的套接字。但是,我似乎收到了很多被截断的消息,或者似乎是被截断的消息。以下是我接收数据的方式:
if((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1)
perror("recv()");
exit(1);
else
buf[numbytes] = '\0';
// Process data
recv()
能否仅接收已发送内容的部分消息?
我的感觉是我可能需要围绕 recv()
调用的另一个循环,直到发送完整的消息。我知道我拥有的 libcurl 实现(我认为这里不可能使用 libcurl)有一个外循环:
// Read the response (sum total bytes read in tot_bytes)
for(tot_bytes=0; ; tot_bytes += iolen)
wait_on_socket(sockfd, 1, 60000L);
res = curl_easy_recv(curl, buf + tot_bytes, sizeof_buf - tot_bytes, &iolen);
if(CURLE_OK != res)
// printf( "## %d", res );
break;
我是否需要一个类似于 libcurl 示例的 recv()
循环(可验证有效)?
【问题讨论】:
不完全相关,但为什么要通过 TCP 发送刻度数据?这些东西通常是通过 UDP 多播的。 我正在接收,而不是发送。他们只是通过电子邮件向我发送了主机名和端口号,我没有收到任何其他技术说明。我刚刚发送了一封电子邮件,询问我是否应该使用 UDP。但是如果我使用 TCP 并且它可以工作(除了我打开主题的部分消息问题)它是否也可以与 UDP 一起工作?即 - 他们发送 UDP,我可以使用 UDP 或 TCP 来接收()?此外,他们确实发送我们也可以将标志传递给recv
以等待所有消息到达。当您知道要接收的字节数时,它就会起作用。你可以像这样传递命令。
numbytes = recv(sockfd, buf, MAXDATASIZE-1, MSG_WAITALL);
【讨论】:
【参考方案2】:你是对的,你需要一个循环。 recv
只检索当前可用的数据;一旦读取了任何数据,它不会等待更多数据出现才返回。
manual page 说 “接收调用通常会返回任何可用的数据,直到请求的数量,而不是等待收到请求的全部数量。”
【讨论】:
【参考方案3】:TCP 不尊重消息边界。这意味着 recv()
不能保证完全按照您的假设获得整个消息。这就是为什么您需要围绕recv()
进行循环的原因。 (这也是为什么像 HTTP 这样的上层协议要么关闭套接字,要么在前面添加一个长度指示符,以便接收者准确地知道何时停止从套接字读取。)
【讨论】:
【参考方案4】:recv() 能否只接收已发送内容的部分消息?
是的,确实,如果您使用 TCP。我认为这可以帮助你。 Handling partial return from recv() TCP in C
【讨论】:
感谢链接。从阅读中,实际上我收到的味精有标题。例如以上是关于recv() 接收部分消息的套接字编程问题的主要内容,如果未能解决你的问题,请参考以下文章
ioctlsocket 或 recv 在 Windows 套接字编程中需要更多时间来执行?