5

我有一个正在接收流式股票报价数据的套接字。但是,我似乎收到了很多被截断的消息,或者似乎是被截断的消息。这是我接收数据的方式:

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;
    }
}

我是否需要一个recv()类似于 libcurl 示例的循环(可验证有效)?

4

4 回答 4

8

我们也可以传递标志来recv等待所有消息都到达。当您知道要接收的字节数时,它就会起作用。您可以像这样传递命令。

numbytes =  recv(sockfd, buf, MAXDATASIZE-1, MSG_WAITALL);
于 2014-12-22T20:35:39.597 回答
7

你是对的,你需要一个循环。 recv只检索当前可用的数据;一旦读取了任何数据,它就不会等待更多数据出现才返回。

手册页说“接收呼叫通常会返回任何可用的数据,直到请求的数量,而不是等待收到请求的全部数量。”

于 2012-04-20T17:20:55.607 回答
3

TCP 不尊重消息边界。这意味着recv()不能保证完全按照您的假设获得整个消息。这就是为什么你需要围绕你的recv(). (这也是为什么像 HTTP 这样的上层协议要么关闭套接字,要么在前面添加一个长度指示符,以便接收者准确地知道何时停止从套接字读取。)

于 2012-04-20T17:20:59.180 回答
1

recv() 可以只接收发送的部分消息吗?

是的,确实,如果您使用 TCP。我认为这可以帮助你。 在 C 中处理来自 recv() TCP 的部分返回

于 2012-04-20T17:20:17.680 回答