首页 > 解决方案 > 从网络服务器 C/C++ 发送的额外字符

问题描述

我正在创建一个简单的网络服务器来将文档发送到浏览器,但是对于某些文档,正在发送额外的字符。最初的 HTML 没问题,但后续的 javascript 和 css 在末尾有额外的字符,使它看起来像是缓冲区溢出。我在堆栈中使用了大约 2048 个字节,我认为这还可以。这是发送文档的代码(文档已经打开并检查它是否正确打开)

    // make header
    char header[MaxSize + 50];
 
    if (other[0] == 0) {
      sprintf(header, "%s 200 %s follows \r\nServer: %s\r\nContent-type: %s\r\n\r\n", httpVer, docuReq, serverType, docT);
    } else {
      sprintf(header, "%s 200 %s follows \r\nServer: %s\r\nContent-type: %s\r\n%s\r\n\r\n", httpVer, docuReq, serverType, docT, other);
    }
 
    send(fd, header, strlen(header), 0);

    // send document
    fseek(document, 0, SEEK_END);
    int bytes = ftell(document);
    fseek(document, 0, SEEK_SET);
    char * buff = (char*)malloc(bytes + 1);
 
    fread(buff, bytes, 1, document);
 
    send(fd, buff, bytes, 0);
    free(buff);
 
    fclose(document);
 
    char closing[5];
    sprintf(closing, "\r\n\r\n");
    closing[4] = 0;
    send(fd, closing, strlen(closing), 0);

更新:该文档以只读方式打开,所以我更改了以下代码

fread(buff, bytes, 1, document);

    int readBytes = fread(buff, 1, bytes, document);
    send(fd, buff, readBytes, 0);

解决了 .js 和 .css 文件发送不正确的问题。不幸的是,图像/GIF 仍然无法正常工作。我检查了 readBytes 和 bytes 之间的区别,readBytes 远低于图像/gif 的字节数。我知道这意味着 fread 中读失败,但我不确定它为什么会失败。

标签: chttpwebserver

解决方案


我猜你fopen是在普通读取模式下的文件 - 不是读取+二进制模式。如果我错了,那么您可能会忽略此答案。:)

但是,如果我是对的,那么我猜您在文件末尾得到的垃圾字符与其中的行数一样多。发生的情况是fread读取\r\n(这是 Windows 中的换行符格式),并将其转换为 only \n(这是大多数其他地方的默认格式)。这意味着每次读取两个\r\n字节时,它只会将一个\n字节放入缓冲区,这意味着缓冲区的最后“行数”字节没有填充数据。

如果您以读取+二进制模式打开文件,则不会发生这种转换,并且您会得到您期望的缓冲区中的字节数。

编辑:

就像@AlanBirtles 评论的那样,您还可以更改:

fread(buff, bytes, 1, document);
send(fd, buff, bytes, 0);

至:

int readBytes = fread(buff, 1, bytes, document);
send(fd, buff, readBytes, 0);

请注意,尽管我更改了调用,因此它现在尝试读取fread大小为 1 的项目数,而不是读取 1 个大小的项目。这是因为fread 手册页bytesbytes

成功时, fread() 和 fwrite() 返回读取或写入的项目数。此数字等于仅当 size 为 1 时传输的字节数。


推荐阅读