接收部分消息的recv()的套接字编程问题

时间:2012-04-20 17:18:01

标签: c linux

我有一个接收流式股票价格数据的套接字。但是,我似乎得到了很多截断的消息,或者似乎是截断的消息。以下是我接收数据的方式:

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()循环(可验证的可行)?

4 个答案:

答案 0 :(得分:6)

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

manual page“接收电话通常会返回所有可用的数据,最多可达到请求的金额,而不是等待收到所请求的全部金额。”

答案 1 :(得分:6)

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

numbytes =  recv(sockfd, buf, MAXDATASIZE-1, MSG_WAITALL);

答案 2 :(得分:2)

TCP不尊重邮件边界。这意味着recv()无法保证获得整个消息,正如您所假设的那样。这就是你需要围绕recv()循环的原因。 (这也是为什么像HTTP这样的上层协议要么关闭套接字,要么预先设置一个长度指示器,所以收件人确切知道何时停止从套接字读取。)

答案 3 :(得分:1)

  

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

是的,确实,如果您使用TCP。我想这可以帮到你。 Handling partial return from recv() TCP in C

相关问题