【问题标题】:read() return positive but there is nothing in recvline [closed]read() 返回正值,但 recvline 中没有任何内容 [关闭]
【发布时间】:2016-06-02 15:23:14
【问题描述】:

我在C中使用socket,我想问一下,正常读取是不是返回正值但什么也不读取?

#define MAXLINE 1234
....
upload(){
....
    long long unsigned int byteNum = 0, count = 0;
    ssize_t nbyte;
    char sendline[MAXLINE], recvline[MAXLINE];
....
    while((count += byteNum) < filesize) {
        bzero(sendline, MAXLINE);
        if((byteNum = fread(&sendline, sizeof(char), MAXLINE, fp)) != MAXLINE ){
            printf("End of file or Error\n");
        }
        if((nbyte = write(sockfd, sendline, byteNum)) < 0){
            printf("upload write error at count = %llu\n", count);
            exit(1);
        }read(sockfd, recvline, MAXLINE);
    }
....

}

download(){
....
    long long unsigned int filesize, count;
    ssize_t nbyte;
    char sendline[MAXLINE], recvline[MAXLINE];
....
        while((count += n) < filesize){
                bzero(recvline, MAXLINE);
                if((nbyte = read(sockfd, recvline, MAXLINE)) < 0){
                    printf("download read fail at %llu\n", count);
                    exit(1);
                }if(nbyte == 0){
                    printf("nbyte = 0!!\n");
                    return;
                }if(strlen(recvline) == 0){
                    printf("nbyte = %zd recvline = 0\n", nbyte);
                    return;
                }
                n = strlen(recvline);
                if(fwrite(&recvline, sizeof(char), nbyte, fp) != nbyte)
                    printf("end of file or error\n");
                write(sockfd, "ok", 2);                 
            }
....
}

结果

nbyte = 1234 recvline = 0

只有当文件很大时才会发生(在测试用例中,它大约为 5GB),但在大约 50MB 时效果很好。

可能出了什么问题?


我已经改变了 nbyte 的类型(从 unsigned long long 变成了 ssize_t)

但结果保持不变

【问题讨论】:

  • 请勿发布外部链接和/或文字图片!这种行为与函数的文档有何矛盾?
  • 请发帖Minimal, Complete, and Verifiable example。你确定nbyte 是签名类型吗?
  • 图像中的 nbyte 65535 看起来非常像分配给无符号 16 位整数的 -1 的 hte 值。
  • printf("nbyte = %llu recvline = 0\n", nbyte); ...那怎么能打印出负值?
  • 请注意,read() 不会以空值终止缓冲区。在您刚刚进入 read() 的缓冲区上调用 strlen() 可能是未定义的行为。

标签: c sockets


【解决方案1】:

我在 C 中使用套接字,我想问一下,这是正常的读取返回吗 正值但什么也没读?

不,这不正常——成功时,read() 总是返回它放入缓冲区的字节数。

可能出了什么问题?

您似乎正在尝试将二进制数据当作 ASCII 文本数据来处理。那是行不通的,因为二进制数据中可能包含 NUL/零字节,并且如果您尝试将其视为文本数据(例如,通过调用 strlen()/strcmp()/strcpy()/etc)那些函数会被那些 NUL 字节的存在所愚弄,因为这些函数期望 NUL 字节来指示字符串的结尾。

特别是,您看到的是,有时写入 recvline 的第一个字节是 0,这就是为什么 strlen(recvline) 返回 0,即使 read() 将一个或多个有效字节写入 recvline。

【讨论】:

    猜你喜欢
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 2021-09-24
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多