C,HTTP 1.1和Socket发送问题

时间:2009-01-10 16:39:20

标签: c http sockets unix

作为我之前关于Creating a web server in pure C的帖子的补充,我在发送功能方面遇到了一些问题。这是两个代码片段:

int Send(char *message)
{
        int length, bytes_sent;
        length = strlen(message);

        bytes_sent = send(connecting_socket, message, length, 0);

        return bytes_sent;
}

此代码将void *发送到当前套接字。像魅力一样工作!

现在发送SendHTML

void SendHTML(char *Status_code, char *Content_Type, char *HTML)
{
        char *head = "\r\nHTTP/1.1 ";
        char *content_head = "\r\nContent-Type: ";
        char *server_head = "\r\nServer: PT06";
        char *length_head = "\r\nContent-Length: ";
        char *date_head = "\r\nDate: ";
        char *newline = "\r\n";
        char Content_Length[100];
        int content_length = strlen(HTML);

        sprintf(Content_Length, "%i", content_length);

        char *message = malloc((
                strlen(head) +
                strlen(content_head) +
                strlen(server_head) +
                strlen(length_head) +
                strlen(date_head) +
                strlen(newline) +
                strlen(Status_code) +
                strlen(Content_Type) +
                strlen(Content_Length) +
                content_length +
                sizeof(char)) * 2);

        if ( message != NULL )
        {
                time_t rawtime;

                time ( &rawtime );

                strcpy(message, head);

                strcat(message, Status_code);

                strcat(message, content_head);
                strcat(message, Content_Type);
                strcat(message, server_head);
                strcat(message, length_head);
                strcat(message, Content_Length);
                strcat(message, date_head);
                strcat(message, (char*)ctime(&rawtime));
                strcat(message, newline);
                strcat(message, HTML);

                Send(message);

                free(message);
        }     
}

如果我要添加

Send("Oh end of HTML Sending eh?");

Send(message)之后和free(message)之前,这不会发送到浏览器?

我认为这可能是HTTP 1.1问题,RFC是否说我只能做一个发送?浏览器收到第一条消息后是否关闭连接?

我如何解决这个问题,以便我可以做到以下几点:

SendHTML("200 OK", "text/plain", "HAaaaii!!");
Send("lolwut?");

这会导致浏览器显示:

  

HAaaaii !! lolwut?

3 个答案:

答案 0 :(得分:6)

由于您发送了内容长度,因此浏览器在“HAaaaii !!”之后将不再接受更多内容因此会解释“lolwut?”作为下一个请求的答案的一部分,这当然会失败。

您可以跳过发送内容长度,但这意味着您没有使用keep-alive,因此无法为每个TCP连接处理多个请求。

每个TCP连接处理多个请求 - 响应交换可以大大加快浏览速度,因为正常的网页由几个单独的资源组成,每个资源都必须单独请求。由于建立TCP连接至少需要3次往返,这会为每个资源增加额外的不必要的延迟。

答案 1 :(得分:4)

head变量中,不应有前导"\r\n"。这可能是导致问题的原因。此外,当你对你的消息进行malloc时,你没有为日期+时间保留足够的空间(根据ctime(3)的文档,26个字节),所以你几乎肯定会覆盖你的缓冲区并导致堆腐败。

如果您想在知道Content-Length的内容之前开始发送数据,则可以使用chunked transfer encoding。分块传输编码说:“我将继续为你提供大量的数据,我可以告诉你每个块有多长,但我不知道有多少块,直到我完成。 “例如,Google使用分块传输编码。以下是使用cURL生成的Google主页的HTTP请求跟踪:

curl www.google.com --trace-ascii -
(标头已剪切 - 但没有Content-Length标头)

数据流由块大小(十六进制)后跟CRLF,然后是数据字节组成。在这种情况下,只有一个块,但可能会有更多。在最后一个块之后,传输块大小为0,表示最后一个块。

答案 2 :(得分:0)

您是否在每个标题后添加换行符?

您可以使用telnet测试您的应用程序,当然看看输出是什么。

不,不需要只有一个发送。假设流式传输2GB文件。这根本不合逻辑。

相关问题