【问题标题】:fprintf failing, but fputc works just fine?fprintf 失败,但 fputc 工作正常吗?
【发布时间】:2013-02-21 02:44:31
【问题描述】:

我正在尝试编写一个通过套接字读取一行文本的函数(这是我为家庭作业编写的 HTTP 服务器代码的一部分)。

当我使用fputc 写入文件时,它可以很好地写入文件。但是,当我尝试将字符复制到缓冲区,然后使用 fprintf 将整个缓冲区打印到文件时,我似乎没有得到任何输出。

代码如下:

int read_line(int fd, char *buffer, int size) {
    char *broken_buffer = (char*) malloc(sizeof(char) * 8096);
    char next = '\0';
    char err;
    int i = 0;
    FILE *f = fopen("read_line2.txt", "w");
    while (i < size - 1 && next != '\n') {
        err = read(fd, &next, 1);
        if (err > 0) {
            if (next == '\r') {
                err = recv(fd, &next, 1, MSG_PEEK);
                if (err > 0 && next == '\n') {
                    read(fd, &next, 1);
                } else {
                    next = '\n';
                }
            }
            fputc(next, f); // Works
            broken_buffer[i] = next;
            buffer[i] = next;
            i++;
        } else {
            next = '\n';
        }
    }
    broken_buffer[i] = '\0';
    buffer[i] = '\0';
    FILE *out = fopen("read_line.txt", "w");
    fprintf(out, "%s\n", broken_buffer); // Does not work
    fclose(out);
    fclose(f);

    return i;
}

编辑:我尝试过使用这个替代功能:

int read_socket(int fd, char *buffer, int size) {
    int bytes_recvd = 0;
    int retries = 0;
    int total_recvd = 0;

    while (retries < MAX_RETRIES && size > 0 && strstr(buffer, ">") == NULL) {
        bytes_recvd = read(fd, buffer, size);

        if (bytes_recvd > 0) {
            buffer += bytes_recvd;
            size -= bytes_recvd;
            total_recvd += bytes_recvd;
        } else {
            retries++;
        }
    }

    if (bytes_recvd >= 0) {
        // Last read was not an error, return how many bytes were recvd
        return total_recvd;
    }
    // Last read was an error, return error code
    return -1;
}

而且我用 fprintf 打印这个没有问题。

EDIT2:我发现i 在循环之后以某种方式为0,因此第一个字符被'\0'覆盖。但是,当我输入调试代码以打印循环中 i 的值时,我发现它被递增到 22(23 是循环中断的最终值)。这怎么可能?结果字符串是:

GET /blah.txt HTTP/1.1

【问题讨论】:

  • 你的套接字是阻塞的还是非阻塞的?如果它被阻塞并且在read 调用中没有更多内容可接收,它将阻塞。
  • 哦,你有内存泄漏。您不需要在堆上分配broken_buffer,只需声明一个普通数组即可。
  • 还记得用"w"打开一个文件覆盖那个文件,所以下次你调用read_line这个文件会被覆盖,这意味着它只会包含last 行读取(可能是空行)。
  • @JoachimPileborg 我认为他们正在阻止,但我已经知道还有更多数据。
  • 我还建议您在调试器中运行它,并逐行执行。

标签: c sockets httpserver


【解决方案1】:

next 的值是否曾经为 0?如果为 0,则该值将进入 broken_buffer,这意味着 fprintf 在您自己显式将 null 放在那里之前会认为它位于字符串的末尾。

【讨论】:

  • 我尝试添加检查以比较 next'\0',似乎没有区别。我使用了一个替代功能(我将其编辑到主帖子中),它使用 fprintf 正确打印到文件。很奇怪。
【解决方案2】:

问题原来是两个进程都连接到服务器(感谢谷歌浏览器...),并且都以某种方式写入同一个文件。代码工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 2016-10-21
    • 1970-01-01
    • 2017-09-30
    • 2018-09-24
    • 2015-10-04
    相关资源
    最近更新 更多