我一直在读通过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。 一个简单的流服务器的指南中。
是的,你需要多recv()
调用,直到你把所有的数据。
要知道什么时候是使用来自返回状态recv()
是没有好处-它只是告诉你,你有多少字节接收,有多少字节没怎么都可以,因为一些仍可能在运输过程。
这是更好,如果你收到莫名其妙的数据编码的总数据的长度。 直到你知道什么长度,然后读取您收到直到读为许多数据length
数据。 要做到这一点,各种方法都是可能的; 常见的一个就是使大到足以容纳所有数据的缓冲区,一旦你知道的长度是多少。
另一种方法是使用固定大小的缓冲器,并总是尝试接收min(missing, bufsize)
降低missing
各后recv()
你需要做的TCP / IP编程时要学会的第一件事:1次write
/ send
呼叫可能需要几个recv
调用来接收和几个写/送话费可能只需要1 recv
调用接收。 和任何在两者之间。
你需要循环,直到你把所有的数据。 的返回值recv()
告诉你多少数据接收。 如果你只是想收到的TCP连接上的所有数据,您可以循环,直到recv()
返回0
-提供的另一端关闭时它完成发送TCP连接。
如果你发送记录/线/包/命令或类似的东西,你需要通过TCP自己的协议,这可能是简单的“命令分隔的\n
”。
读/解析这样的命令的简单的方法是在一次读取1个字节,建立与所述接收到的字节的缓冲,然后检查\n
每次一个字节。 读1个字节是极其低效的,所以你应该一次读取较大的块。
由于TCP是面向流并没有提供它变得更加麻烦一些,记录/消息边界-你不得不recv
一块字节,检查接收缓冲区的\n
字节,如果它的存在-字节追加到先前接收到的消息字节和输出。 然后检查后缓冲区的剩余\n
-这可能包含另一个整条消息或只是另一个消息的开始。
是的,你必须遍历recv()
直到收到'\0'
或错误发生(从负值recv
或) 0
距离recv()
对于第一种选择:仅当此零是你的协议的一部分(该服务器发送它)。 但是从你的代码似乎是零,只是为了能够使用缓冲区内容作为C-字符串(在客户端)。
对于返回值的检查0
从recv
:这意味着连接被关闭(也可能是你的协议,出现这种情况的一部分。)