搜索

首页  >  问答  >  正文

c++ - 如何判断read函数是否完整读完?

#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_leeringa_lee2807 天前983

全部回复(3)我来回复

  • PHP中文网

    PHP中文网2017-04-17 13:18:18

    根据read的返回值判断:
    size = read(somefd, someBuffer, length);
    size > 0 //size就是实际读取到的长度
    size == 0 //读到eof了,读取结束
    size < 0 //发生错误,要检查errno

    man 2 read:
    返回值
    成功时,返回读取的字节数(零表示文件结尾),并且文件位置将前进该数字。 如果该数字小于请求的字节数,则不是错误;例如,这可能会发生,因为现在实际可用的字节较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为 read() 被信号。 出错时,返回 -1,并适当设置 errno。 在这种情况下,文件位置(如果有)是否改变是未指定的。

    回复
    0
  • 巴扎黑

    巴扎黑2017-04-17 13:18:18

    socket实际上是一个流, 流你就没办法判断是不是读完了. 你一次从流里面读取若干个字节, 然后在逻辑层判断包是否完整, 就只能这样做. 所以逻辑层是需要有一个单独的缓冲区的, 用来存放还没有完全解码的包, 等读完整了, 再解码, 释放掉.

    回复
    0
  • ringa_lee

    ringa_lee2017-04-17 13:18:18

    什么叫做完整读完就不好界定,很模糊。
    双方使用的是什么通信协议,协议里应该规定的有什么叫做“读完了”

    就像 @胡须老头 和 @egmkang 说的那样

    • 反正read返回0就表示EOF,在socket中就表示对方关闭了连接, 关闭连接的原因很多,比如:认为你连接不合法、出错了或者就是“发送完毕”,反正就是对方有意的、主动的关闭了连接

    • read返回值大于0就表示本次read了多少个字节

    • read返回值小于0,就表示出错了,看errno就能知道错误原因,比如Timeout等原因

    至于一次读不完一次发不满一点儿一点儿发,那你就缓存呗!,直到读到EOF或者逻辑判断读完了。

    回复
    0
  • 取消回复