【发布时间】:2014-01-21 10:03:52
【问题描述】:
我有一个使用套接字的自定义 HTTP 服务器和一个使用 HttpWebRequest 连接到该服务器的客户端。客户端是多线程的,使用这段代码:
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 48;
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = verb;
request.Timeout = timeout;
request.AutomaticDecompression = DecompressionMethods.GZip;
request.Proxy = null;
request.SendChunked = false;
/*offending lines*/
var writer = new StreamWriter(request.GetRequestStream(),Encoding.UTF8);
writer.Write(stringData);
writer.Close();
/*end offending lines*/
var response = (HttpWebResponse)request.GetResponse();
我已经通过这段代码运行了数千个请求,并且大部分时间都运行良好。平均响应时间约为 200 毫秒,包括在服务器上完成的一些工作。
问题是大约 0.2% 的请求非常慢。在测量时,我注意到缓慢的请求在获取和写入请求流时会暂停 3 秒(+- 20 毫秒)。 GetResponse() 仍然很快,服务器上没有任何东西需要额外的时间。
服务器被实现为一个侦听器 Socket 在端口上异步侦听,使用 Listen() 和 BeginAccept()。接受连接后,在新的 Socket 上调用 BeginRecieve(从 EndAccept() 获取)并在侦听器套接字上再次调用 BeginAccept。根据我的阅读,这是这样做的方法。
所以我的问题是:在 GetRequestStream() 和写入期间会发生什么?数据实际上是在此处发送还是在 GetResponse() 上刷新?为什么有些请求会在没有任何明显原因的情况下多花 3 秒?我的服务器实现是否存在某种缺陷?奇怪的是它总是 3 秒,但有时可能是 9 秒。由于某种原因,它似乎是 3 的倍数。
几种可能的情况:
- 连接是在 GetRequestStream() 上启动的,但服务器不会立即接受它。如果是这种情况,我该如何测试?
- GetRequestStream() 的幕后发生了一些事情或正在对其进行写入。
- 等待网络硬件?
- 等待 DNS 解析?
- 还有别的吗?
非常感谢任何帮助。
编辑:我尝试通过 Web 代理进行连接,然后延迟从 GetRequestStream() 移动到 GetResponse(),表明问题确实出在 Web 服务器上。似乎它不接受连接。我意识到 EndAccept() 和 BeginAccept() 之间可能会有一些延迟,但它不应该等于 3 秒的延迟,对吧?
我也尝试过单线程运行我的客户端,问题似乎消失了。这表明只有同时发出多个请求时才会出现连接延迟。
【问题讨论】:
标签: c# sockets http httpwebrequest