- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 HttpWebRequest 连接到我内部构建的 HTTP 服务器。我的问题是它比通过例如 PostMan ( https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en ) 连接到服务器慢很多,后者可能使用 Chrome 中的内置函数来请求数据。
服务器是使用 MSDN ( http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx ) 上的这个示例构建的,并使用大小为 64 的缓冲区。该请求是一个 HTTP 请求,正文中包含一些数据。
当通过 PostMan 连接时,请求被分成一堆 block 并且 BeginRecieve() 被调用多次,每次接收 64B 并花费大约 2 毫秒。除了最后一个,它接收不到 64B。
但是当使用 HttpWebRequest 连接到我的客户端时,第一个 BeginRecieve() 回调接收到 64B 并花费了大约 1 毫秒,接下来仅接收到 47B 并花费了将近 200 毫秒,最后第三个接收到大约 58B 并花费了 2 毫秒。
第二个 BeginRecieve 是怎么回事?我注意到,一旦我开始将数据写入 HttpWebRequest 输入流,就会建立连接,但在我调用 GetResponse() 之前数据接收不会开始。
这是我的 HttpWebRequest 代码:
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = verb;
request.Timeout = timeout;
request.Proxy = null;
request.KeepAlive = false;
request.Headers.Add("Content-Encoding", "UTF-8");
System.Net.ServicePointManager.Expect100Continue = false;
request.ServicePoint.Expect100Continue = false;
if ((verb == "POST" || verb == "PUT") && !String.IsNullOrEmpty(data))
{
var dataBytes = Encoding.UTF8.GetBytes(data);
try
{
var dataStream = request.GetRequestStream();
dataStream.Write(dataBytes, 0, dataBytes.Length);
dataStream.Close();
}
catch (Exception ex)
{
throw;
}
}
WebResponse response = null;
try
{
response = request.GetResponse();
}
catch (Exception ex)
{
throw;
}
var responseReader = new StreamReader(rStream, Encoding.UTF8);
var responseStr = responseReader.ReadToEnd();
responseReader.Close();
response.Close();
我做错了什么?为什么它的行为与来自 Web 浏览器的 HTTP 请求如此不同?这实际上为我的应用程序增加了 200 毫秒的延迟。
最佳答案
这看起来像是 Nagle algorithm 的典型案例与TCP Delayed Acknowledgement发生冲突.在您的情况下,您正在发送一个小的 Http 请求(根据您的数字约为 170 个字节)。这可能小于 MSS(最大段大小),这意味着 Nagle 算法将启动。服务器可能会延迟 ACK,导致最多 500 毫秒的延迟。有关详细信息,请参阅链接。
您可以通过 ServicePointManager.UseNagleAlgorithm = false
禁用 Nagle(在发出第一个请求之前),参见 MSDN .
另见 Nagle’s Algorithm is Not Friendly towards Small Requests详细讨论,包括 Wireshark 分析。
注意:在您的回答中,当您进行写入-写入-读取时,您会遇到同样的情况。当你切换到写-读时,你就克服了这个问题。但是,我不相信您可以指示 HttpWebRequest(或 HttpClient)将小请求作为单个 TCP 写入操作发送。在某些情况下,这可能是一个很好的优化。虽然它可能会导致一些额外的数组复制,从而对性能产生负面影响。
关于c# - HttpWebRequest 对于分块数据很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18465504/
我正在使用 HttpWebRequest 登录页面并获取一些信息。然后,我使用该信息创建一个新的 HttpWebRequest 以获取更多信息。我不想使用 WebClient。 如何将使用第一个 Ht
我有一个包含指向某些文件的链接的页面。 我基本上需要访问页面的源代码来解析它并获取文件的所有超链接。 我的代码是这样的(我在网上很多地方都找到了一些代码..): "private static
我正在编写一个渐进式下载器作为可移植类库 (Profile=24)。它将支持以字节 block 的形式部分下载目标文件。 HttpClient 不可用,我将使用 HttpWebRequest,它具有用
我正在努力在 HttpWebRequest 之上构建一个流畅的 REST 客户端界面。/HttpWebResponse .NET 中的类型。到目前为止,一切都很好......但是我正在尝试开发一个可插
我有一个用 VB.NET 编写的应用程序( 不是 asp.net,它是一个 Windows 控制台应用程序)。我正在尝试调用一个 url(一个 html 页面)并将响应返回到一个字符串中。响应是直接的
我尝试使用 C# HTTPWebRequest 类登录 amazon.com,我可以登录但无法读取 header 中的多个 set-cookie 当服务器响应多个“Set-Cookie:”-heade
我正在测试 Web 核心 API,但收到 500 内部服务器错误。 我的 Controller 上的方法是; [Route("api/property")] public class Property
假设我正在检索一个 url,如下所示: string url = "http://www.somesite.com/somepage.html" HttpWebRequest req = (HttpW
当我使用 HttpWebRequest.Headers.Add("Cookie",value) 与 HttpWebRequest.CookieContainer 和结果从 HttpWebRequest
我已阅读以下 2 篇文章并尝试实现相同的文章。 我的代码是这样的,超时发生在这里 HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
我正在寻找一种使用 httpWebRequest 从 url 下载 excel 文件并以某种方式解析它的方法 - 这是否意味着将其转换为 .csv 文件,以便我可以简单地使用 TextFieldPar
当我尝试序列化 HttpWebRequest 时出现以下错误 Type 'System.Net.KnownHttpVerb' in Assembly 'System, Version=2.0.0.0,
我目前正在下载一个 HTML 页面,使用以下代码: Try Dim req As System.Net.HttpWebRequest = DirectCast(WebRequest.Creat
我读了这个 MSDN 喜欢它并运行它的例子。 http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.useragent.a
我有一个 ASP.NET MVC 操作,它通过 HttpWebRequest 将 GET 请求发送到另一台服务器。我想在新请求中包含原始操作请求中的所有 cookie。原始请求中的一些 System.
我正在尝试抓取具有用户身份验证的网站。我能够执行POST来发送登录信息并存储Cookie。但是,登录后,尝试访问 protected 页面时出现403错误。 $url = "https://some_
我正在使用 HttpWebRequest ,并且正在处理响应流。 HttpWebRequest是否有正确的处理方法? ,因为它不包含 close 或 dispose 方法? 最佳答案 如果该类有特殊的
我在REST服务中抛出一个错误,例如: throw new WebFaultException("bla bla bla", HttpStatusCode.HttpVersionNotSuppo
问题:此控制台应用调用 Azure 上托管的长时间运行的网页两次。我希望它只调用一次。 控制台应用程序因捕获的异常而失败:基础连接已关闭:接收时发生意外错误。 so question 如果我从 Chr
我试图弄清楚我的网络请求在最终到达最终内容之前被重定向了多少次。 我正在创建我的网络请求,如下所示: var httpRequest = (HttpWebRequest) WebRequest.Cre
我是一名优秀的程序员,十分优秀!