C - 套接字,分隔数据和http标头?

时间:2017-03-18 11:13:48

标签: c sockets http client-server

我正在尝试模拟客户端/服务器通信以使用套接字和http请求发送和接收文件。

客户端向服务器发送一个http请求,表示他们想要下载一个简单的.txt文件,服务器将文件数据发送回客户端,并带有一个http响应头。

但是,写入接收文本文件的数据还包含不应该包含的http标头信息。

如何有效地将http标头与实际数据分开?

这是代码的样子:

服务器

//receives an http header request from client saying they want to download a .txt file

bzero(buffer, 256);

sprintf(buffer, "HTTP/1.1 200 OK\r\n Date:%s\r\n Content-Type:%s\r\n Content-Length:%s\r\n\r\n", time, content, length);

data = write(incoming_socket, buffer, strlen(buffer)); // first sends an http response header

bzero(buffer, 256);

int data;

while((data = fread(buffer, sizeof(char), 256, fs)) > 0){

    if(send(cli_socket, buffer, strlen(buffer), 0) < 0){ // sends the actual file data to client in this while cycle 

        perror("ERROR: Could not send file.");
        break;
        exit(EXIT_FAILURE);
    }

    if (block_size < 256){

        if (ferror(fs)){

            perror("ERROR: Failed while sending data.");
            exit(EXIT_FAILURE);
        }

        bzero(buffer, 256);

        break;
    }

    bzero(buffer, 256);
}

客户端:

bzero(buffer, 256);

data = read(client_socket, buffer, 256); // first receive the http header response 

bzero(buffer, 256);

while (1){

    data = recv(client_socket, buffer, 256, 0); // receive data

    fwrite(buffer, sizeof(char), data, fr); // write data into the file 

    bzero(buffer, 256);

    if (data == 0 || data < 256){

        fclose(fr);
        break;
    }

    if(data< 0){

        printf("failed while copyng file!\n");
        exit(1);
    }
}

但是,这也会使用http响应填充.txt文件,而不仅仅是数据。

现在,我知道我应该在标题响应中查找/ r / n / r / n,以便分隔标题并只写出实际数据,但是,如果有人可以告诉我最好的方法来执行此操作在我的示例中使用我的特定缓冲区,我将非常感激!

1 个答案:

答案 0 :(得分:2)

不幸的是,您选择了非常的compelex协议来实现。您唯一的选择是阅读HTTP版本1.1的文档并精确遵循规范。该文档将告诉您如何识别标题的结尾。请注意,必须支持分块编码。它是HTTP 1.1合规性所必需的。

但你真的选择了一枚氢弹在这里杀死一只蚂蚁。 HTTP 1.1是一种复杂的高性能协议,也是一种糟糕的选择,只是搞乱传输文件。

还有一些错误:

if(send(cli_socket, buffer, strlen(buffer), 0) < 0){ // sends the actual file data to client in this while cycle 

strlen函数仅适用于C风格的字符串,而不适用于任意数据。 recv函数返回原因读取的字节数。

data = recv(client_socket, buffer, 256, 0); // receive data

fwrite(buffer, sizeof(char), file_block_size, fr); // write data into the file

当然,您编写的字节数应该是您读取的字节数(有助于存储在变量data中,但未使用),而不是其他数字。

如果你真的想制作HTTP 1.1客户端和服务器代码,那么你真的应该从彻底了解HTTP 1.1规范和示例客户端和服务器代码开始。但这是学习如何发送和接收文件的可怕的方式,因为HTTP 1.1非常复杂。