c++ - 如何判断read函数是否完整读完?
ringa_lee
ringa_lee 2017-04-17 13:16:18
0
3
978
#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判断吗?

ringa_lee
ringa_lee

ringa_lee

全部回复(3)
洪涛

根据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或者逻辑判断读完了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板