#define MAX 500
char _readbuf[MAX];
while (read(socket_fd, _readbuf, MAX) > 0)
{
printf("%s", _readbuf);
if (strlen(_readbuf) < MAX) // 我用这种方式来判断是否读完
break;
memset(_readbuf, 0, MAX);
}
但是如果网速慢或者对方主机当掉的话,这样又读不完整了,就是不会一次性发满给你,分一点点发,那我这样判断是否读完又不行了。请问用read函数怎么实现完整读完对方发来的数据?
再具体一点,我在实现一个ftp客户端,比如我向服务端发送一个HELP命令,服务器会返回一串字符串的,结尾肯定是\r\n,但不保证\r\n出现一次,是否能判断逻辑读完?其实我就是不知道如何判断read是否完整读完。因为它就是返回一个字符串,能用EOF判断吗?
根据read的返回值判断:
size = read(somefd, someBuffer, length);
size > 0 //size就是实际读取到的长度
size == 0 //读到eof了,读取结束
size
man 2 read:
返回值
成功时,返回读取的字节数(零表示文件结尾),并且文件位置将前进该数字。 如果该数字小于请求的字节数,则不是错误;例如,这可能会发生,因为现在实际可用的字节较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为 read() 被信号。 出错时,返回 -1,并适当设置 errno。 在这种情况下,文件位置(如果有)是否改变是未指定的。
socket实际上是一个流, 流你就没办法判断是不是读完了. 你一次从流里面读取若干个字节, 然后在逻辑层判断包是否完整, 就只能这样做. 所以逻辑层是需要有一个单独的缓冲区的, 用来存放还没有完全解码的包, 等读完整了, 再解码, 释放掉.
什么叫做
完整读完
就不好界定,很模糊。双方使用的是什么通信协议,协议里应该规定的有什么叫做
“读完了”
就像 @胡须老头 和 @egmkang 说的那样
反正read返回0就表示EOF,在socket中就表示对方关闭了连接, 关闭连接的原因很多,比如:认为你连接不合法、出错了或者就是
“发送完毕”
,反正就是对方有意的、主动的关闭了连接
read返回值大于0就表示本次read了多少个字节
read返回值小于0,就表示出错了,看errno就能知道错误原因,比如Timeout等原因
至于
一次读不完
、一次发不满
、一点儿一点儿发
,那你就缓存呗!,直到读到EOF或者逻辑判断读完
了。