处理来自的recv()TCP用C部分返回(Handling partial return from

2019-07-05 04:45发布

我一直在读通过Beej指南网络编程获取TCP连接的句柄。 在该样品中的一项所述的用于简单的TCP流客户端在客户端的代码如下所示:

if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
    perror("recv");
    exit(1);
}

buf[numbytes] = '\0';

printf("Client: received '%s'\n", buf);

close(sockfd);

我已经设置了缓冲区,比我送的总字节数小。 我不太肯定我怎么能得到其他字节。 我必须遍历recv()直到我收到'\0'

*注意:在服务器端,我也实现了他sendall()函数,所以它实际上应该都发送到客户端。

另见6.1。 一个简单的流服务器的指南中。

Answer 1:

是的,你需要多recv()调用,直到你把所有的数据。

要知道什么时候是使用来自返回状态recv()是没有好处-它只是告诉你,你有多少字节接收,有多少字节没怎么都可以,因为一些仍可能在运输过程。

这是更好,如果你收到莫名其妙的数据编码的总数据的长度。 直到你知道什么长度,然后读取您收到直到读为许多数据length数据。 要做到这一点,各种方法都是可能的; 常见的一个就是使大到足以容纳所有数据的缓冲区,一旦你知道的长度是多少。

另一种方法是使用固定大小的缓冲器,并总是尝试接收min(missing, bufsize)降低missing各后recv()



Answer 2:

你需要做的TCP / IP编程时要学会的第一件事:1次write / send呼叫可能需要几个recv调用来接收和几个写/送话费可能只需要1 recv调用接收。 和任何在两者之间。

你需要循环,直到你把所有的数据。 的返回值recv()告诉你多少数据接收。 如果你只是想收到的TCP连接上的所有数据,您可以循环,直到recv()返回0 -提供的另一端关闭时它完成发送TCP连接。

如果你发送记录/线/包/命令或类似的东西,你需要通过TCP自己的协议,这可能是简单的“命令分隔的\n ”。

读/解析这样的命令的简单的方法是在一次读取1个字节,建立与所述接收到的字节的缓冲,然后检查\n每次一个字节。 读1个字节是极其低效的,所以你应该一次读取较大的块。

由于TCP是面向流并没有提供它变得更加麻烦一些,记录/消息边界-你不得不recv一块字节,检查接收缓冲区的\n字节,如果它的存在-字节追加到先前接收到的消息字节和输出。 然后检查后缓冲区的剩余\n -这可能包含另一个整条消息或只是另一个消息的开始。



Answer 3:

是的,你必须遍历recv()直到收到'\0'或错误发生(从负值recv或) 0距离recv() 对于第一种选择:仅当此零是你的协议的一部分(该服务器发送它)。 但是从你的代码似乎是零,只是为了能够使用缓冲区内容作为C-字符串(在客户端)。

对于返回值的检查0recv :这意味着连接被关闭(也可能是你的协议,出现这种情况的一部分。)



文章来源: Handling partial return from recv() TCP in C
标签: c++ c sockets tcp