HTTP 服务器未向 WGET、Firefox 发送完整文件.对等方重置连接? [英] HTTP Server Not Sending Complete File To WGET, Firefox. Connection reset by peer?

查看:17
本文介绍了HTTP 服务器未向 WGET、Firefox 发送完整文件.对等方重置连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写 HTTP 服务器,但无法发送较大的文件.如果我用 netcat 抓取它们,输出看起来很完美.如果我使用浏览器或 wget,有时我只能获得完整的文件.WGET 不断收到对等连接重置"错误,请参见下面的输出.Firefox 说连接已重置".

I'm writing an HTTP server, and am having trouble sending larger files. If I grab them with netcat, the output seems perfect. If I use a browser or wget, I only get the complete file sometimes. WGET keeps getting "connection reset by peer" errors, see the output below. Firefox says "the connection was reset".

以下是向客户端发送数据的相关过程:

Here's the relevant procedure that sends data to the client:

int handle_request(int sockfd, struct cached_file content) {
    char buffer[1024]; // FIXME hardcoded arbitrary buffer size for header

    unsigned int sent_bytes;
    unsigned int total = 0;
    unsigned int bytes_left = content.size;

    printf("I have to send %u bytes of content.
", content.size);

    snprintf(buffer, 1024, "HTTP/1.1 %s
Content-Type: %s
Content-Length: %s

", content.statuscode, content.contenttype, content.sizestring);
    sent_bytes = send(sockfd, buffer, strlen(buffer), MSG_MORE);
    printf("I wanted to send %u bytes of header, and I sent %u.
", strlen(buffer), sent_bytes);

    while (total < bytes_left) {
        sent_bytes = send(sockfd, content.data+total, bytes_left, 0);
        if (sent_bytes == -1) { 
            printf("send() returned -1
");
            break; 
        }

        total      += sent_bytes;
        bytes_left -= sent_bytes;
    }
    printf("I sent %u bytes of content. I had %u left to send.
", total, bytes_left);

    if (sent_bytes == -1)
        logprint("socket error!", errno);
}

这是 wget 尝试抓取文件的输出:

Here's the output from wget trying to grab the file:

wget --tries 1 http://localhost:8081/image.jpg
--2015-07-01 13:21:42--  http://localhost:8081/image.jpg
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8081... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8081... connected.
HTTP request sent, awaiting response... 200 OK
Length: 700895 (684K) [image/jpeg]
Saving to: ‘image.jpg.10’

image.jpg.10                      53%[===============================>                             ] 363.31K  --.-KB/s   in 0.001s 

2015-07-01 13:21:42 (688 MB/s) - Read error at byte 372031/700895 (Connection reset by peer). Giving up.

wget --tries 1 http://localhost:8081/image.jpg
--2015-07-01 13:21:43--  http://localhost:8081/image.jpg
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8081... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8081... connected.
HTTP request sent, awaiting response... 200 OK
Length: 700895 (684K) [image/jpeg]
Saving to: ‘image.jpg.11’

image.jpg.11                       6%[==>                                                          ]  42.69K  --.-KB/s   in 0s     

2015-07-01 13:21:43 (500 MB/s) - Read error at byte 43711/700895 (Connection reset by peer). Giving up.

http 服务器的调试输出:

Debugging output from the http server:

I have to send 700895 bytes of content.
I wanted to send 65 bytes of header, and I sent 65.
I sent 700895 bytes of content. I had 0 left to send.

我希望能有另一双关注这个问题!为什么会发生这种情况,我该如何解决?

I'd appreciate another set of eyes on this! Why is this happening and how can I fix it?

推荐答案

我的猜测是该错误与您未在此处显示的代码有关.

My guess is that the error is related to code you have not shown here.

简单实现中的常见错误是不完全读取请求,而是仅读取第一行或一些字节以确定请求的页面,然后发送响应并最终关闭.

It is a common mistake in simple implementation to not fully read the request but instead only read the first line or some bytes to determine the requested page, then send the response and finally close.

由于在关闭的时候还有来自客户端的未读数据,这将导致连接被对端重置.nc 看不到这种效果,因为您使用 nc 发送的请求可能比来自浏览器的请求短,因此在 nc 的情况下会读取来自请求的所有数据,但在浏览器的情况下则不会.

Since at the time of the close there are still unread data from the client, this will result in Connection reset by peer. You don't see this effect with nc because the request you send with nc is probably shorter than the request from the browser and thus all data from the request are read in case of nc, but not in case of browser.

除此之外,即使浏览器接受,您的响应也是无效的.您的状态行(第一行)在状态代码之后停止,而不是添加原因短语,请参阅 http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.此外,您使用 而不是 作为行分隔符.

Apart from that your response is invalid even if browsers accept it. Your status line (the first line) stops after the status code instead of adding the reason phrase, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1. Also, you use instead of as line delimiter.

这篇关于HTTP 服务器未向 WGET、Firefox 发送完整文件.对等方重置连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆