찾다

 >  Q&A  >  본문

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_lee2806일 전980

모든 응답(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:
    RETURN VALUE
    On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case, it is left unspecified whether the file position (if any) changes.

    회신하다
    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
  • 취소회신하다