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

如何防止httpwebrequest的数据包碎片化

  •  7
  • piers7  · 技术社区  · 14 年前

    我在嵌入式设备上对HTTP守护程序使用httpwebrequest时遇到问题。问题似乎是在写入套接字流的HTTP头和HTTP有效负载(POST)之间存在足够的延迟,套接字将套接字缓冲区中的内容释放到服务器。这会导致HTTP请求被拆分为两个数据包(碎片)。

    当然,这是完全有效的,但是如果数据包被拆分超过1.8ms,另一端的服务器将无法处理它。所以我想知道是否有任何实际的方法来控制它(在客户机上)。

    httpwebrequest上似乎没有任何属性可以对用于发送的套接字提供这种级别的控制,并且似乎无法访问套接字本身(即通过反射),因为它只在发送期间创建,之后发布(作为出站HTTP连接池内容的一部分)。BufferWriteStream属性只是缓冲WebRequest中的主体内容(因此它仍然可用于重定向等),并且似乎不会影响整个请求写入套接字的方式。

    那么该怎么办呢?

    (我真的想避免从套接字重新编写HTTP客户机)

    一种选择可能是编写httpwebrequest发送到的某种代理(可能通过servicepoint),并在该实现中缓冲整个tcp请求。但这似乎是一项艰巨的工作。

    当我运行fidder(出于同样的原因)时,它也可以正常工作,但在我们的生产环境中,这不是一个真正的选项…

    [注:我知道问题出在碎片包之间的间隔,因为我搞砸了一个套接字级别的测试,在测试中我使用一个节点套接字显式地控制碎片]

    4 回复  |  直到 12 年前
        1
  •  2
  •   piers7    13 年前

    最后,供应商推出了一个固件升级,其中包括一个新版本的httpd,问题就消失了。他们使用的是busybox-linux,显然HTTPD实现还有其他一些问题。

    就我最初的问题而言,我认为没有 任何 除了编写一个套接字代理之外,还可以使用可靠的方法来完成这项工作。我在上面玩过的一些解决方法是运气而不是设计(因为它们意味着.NET一次性发送了整个包)。

        2
  •  1
  •   piers7    14 年前

    什么有 似乎 要修复此问题,需要在与该URI关联的服务点上禁用Nagling,并以HTTP 1.0的形式发送请求(两者都不修复此问题):

    var servicePoint = ServicePointManager.FindServicePoint(uri.Uri);
    servicePoint.UseNagleAlgorithm = false;
    

    然而,这似乎只是通过使请求更快地发出,而不是强制将头和有效负载写入一个包来解决问题。因此,它可能在加载的机器上失败/高延迟链接等。

    想知道写一个碎片整理代理有多困难…

        3
  •  0
  •   feroze    14 年前

    您的嵌入式服务器是HTTP/1.1服务器吗?如果是,请在调用GetRequestStream()之前,尝试在WebRequest上设置expect100continue=false。这将确保在发送实体体之前,HTTP堆栈不期望服务器发出“http/1.1 100 continue”头响应。因此,即使数据包仍将在头和主体之间被拆分,数据包之间的间隙也将变短。

        4
  •  0
  •   jamespconnor    12 年前

    就在客户端拆分数据包的问题上,我发布了一个与此问题相关的问题的答案:

    我在这里看到了答案:

    http://us.generation-nt.com/answer/too-packets-httpwebrequest-help-23298102.html

    推荐文章