代码之家  ›  专栏  ›  技术社区  ›  Handcraftsman

由于HTTP响应中的内容长度=0,有助于消除异步接收器中的循环

  •  2
  • Handcraftsman  · 技术社区  · 15 年前

    某些Web服务器在HTTP响应头中将内容长度设置为零。我想要一个确定性和性能的解决方案来接收这种情况下的所有数据。

    显示此行为的已知URL(下面的其他URL):

    http://www.washingtonpost.com/wp-dyn/content/article/2010/02/12/AR2010021204894.html?hpid=topnews

    页眉:

    Cache-control:no-cache
    Connection:close
    Content-Encoding:gzip
    Content-type:text/html
    Server:Web Server
    Transfer-encoding:chunked
    

    我当前的解决方案不能保证获得所有的数据,因为maxtries常量,并且由于thread.sleep()而变慢。

    private bool MoreDataIsAvailable()
    {
        int avail = _socket.Available;
        if (avail == 0 &&
            _contentLength != null && _contentLength == 0)
        {
            int tries = 0;
            while (avail == 0 && tries < MaxTries)
            {
                Thread.Sleep(5);
                _socket.Poll(1000, SelectMode.SelectRead);
                avail = _socket.Available;
                tries++;
                if (avail > 0)
                {
                    Console.WriteLine(_socket.Handle + " avail = " + avail + " received = " + _bytes.Length + " && tries = " + tries);
                }
            }
        }
        return avail > 0;
    }
    

    上下文中的用法:

    private void ReceiveCallback(object sender, SocketAsyncEventArgs e)
    {
        if (ConnectionWasClosed(e) || HadSocketError(e))
        {
            _receiveDone.Set();
            return;
        }
    
        StoreReceivedBytes(e);
    
        if (AllBytesReceived())
        {
            _receiveDone.Set();
            return;
        }
    
        if (MoreDataIsExpected() || MoreDataIsAvailable())
        {
            WaitForBytes(e);
        }
        else
        {
            _receiveDone.Set();
        }
    }
    

    样品输出:

    1436 avail = 3752 received = 1704 && tries = 9
    1436 avail = 3752 received = 9208 && tries = 8
    1436 avail = 3752 received = 12960 && tries = 9
    1436 avail = 3752 received = 20464 && tries = 8
    1436 avail = 3752 received = 27968 && tries = 7
    1436 avail = 7504 received = 31720 && tries = 1
    1436 avail = 3752 received = 39224 && tries = 6
    

    编辑:

    尼古拉观察到 传输编码:分块 头需要特殊处理,但其末端可以确定地检测到。

    但是,除了分块的响应之外,还有其他URL最终出现在我的catch all方法中,例如:

    http://www.biomedcentral.com/1471-2105/6/197

    页眉:

    Cache-control:private
    Connection:close
    Content-Type:text/html
    P3P:policyref="/w3c/p3p.xml", CP="NOI DSP COR CURa ADMa DEVa TAIa OUR BUS PHY ONL UNI COM NAV INT DEM PRE"
    Server:Microsoft-IIS/5.0
    X-Powered-By:ASP.NET
    

    http://slampp.abangadek.com/info/

    页眉:

    Connection:close
    Content-Type:text/html
    Server:Apache/2.2.8 (Ubuntu) DAV/2 PHP/5.2.4-2ubuntu5.3 with Suhosin-Patch mod_ruby/1.2.6 Ruby/1.8.6(2007-09-24) mod_ssl/2.2.8 OpenSSL/0.9.8g
    X-Cache:MISS from server03.abangadek.com
    X-Powered-By:PHP/5.2.4-2ubuntu5.3
    

    http://video.forbes.com/embedvideo/?format=frame&height=515&width=336&mode=render&networklink=1

    页眉:

    Connection:close
    Content-Language:en-US
    Content-Type:text/html;charset=ISO-8859-1
    Server:Apache-Coyote/1.1
    

    我想知道我可以在这些响应中查找什么,就像第一个URL的传输编码头一样,它提供了一个线索,可以确定地读取整个响应,从而避免对我的方法的调用。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Nikolai Fetissov    15 年前

    从给出的网址来看 HTTP Chunked Transfer Encoding 允许服务器在知道总长度之前开始传输响应,同时允许客户端可靠地确定响应的结束。

    也看到 RFC 2616, section 3.6.1 .