HttpWebRequest.GetResponse()不断超时

sym*_*ont 17 .net c# httpwebrequest mtgox

我写了一个简单的C#函数,通过以下API调用从MtGox检索交易历史:

https://data.mtgox.com/api/1/BTCUSD/trades?since=<trade_id>
Run Code Online (Sandbox Code Playgroud)

记录在这里:https://en.bitcoin.it/wiki/MtGox/API/HTTP/v1#Multi_currency_trades

这是功能:

string GetTradesOnline(Int64 tid)
{
    Thread.Sleep(30000);

    // communicate
    string url = "https://data.mtgox.com/api/1/BTCUSD/trades?since=" + tid.ToString();
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream());

    string json = reader.ReadToEnd();
    reader.Close();
    reader.Dispose();
    response.Close();

    return json;
}
Run Code Online (Sandbox Code Playgroud)

我从tid = 0(交易ID)开始获取数据(从一开始).对于每个请求,我收到一个包含1000个交易详情的回复.我总是从前一个响应中发送交易ID以用于下一个请求.它适用于4个请求和响应.但在此之后,以下行抛出"System.Net.WebException",表示"操作已超时":

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Run Code Online (Sandbox Code Playgroud)

这是事实:

  • 捕获异常并重新输入会导致同样的异常
  • 默认的HttpWebRequest .Timeout和.ReadWriteTimeout已经足够高(超过一分钟)
  • 将HttpWebRequest.KeepAlive更改为false也没有解决任何问题
  • 它似乎总是在浏览器中工作,即使功能失败
  • https://www.google.com检索响应没有问题
  • 异常变化之前成功响应的数量每天都不同(但浏览器始终有效)
  • 从上次失败的交易ID开始会立即导致异常
  • 从主线程调用此函数仍然导致异常
  • 在另一台机器上运行它不起作用
  • 从不同的IP运行它不起作用
  • 在请求之间增加Thread.Sleep没有帮助

什么可能是错的?

Hab*_*eeb 25

我有同样的问题.对我来说,修复就像在使用块中包装HttpWebResponse代码一样简单.

using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
{
    // Do your processings here....
}
Run Code Online (Sandbox Code Playgroud)

详细信息:当对同一主机发出多个请求并且WebResponse未正确处理时,通常会发生此问题.这就是using块将正确地妥善处理WebResponse对象并从而解决问题的地方.


kev*_*n c 20

有两种超时.客户端超时和服务器超时.你有没有试过这样的事情:

request.Timeout = Timeout.Infinite;
request.KeepAlive = true;
Run Code Online (Sandbox Code Playgroud)

尝试这样的事......

  • 是的,请注意一堆请求,因为服务器会识别这一点并关闭流量,因为这通常是拒绝服务,这将阻止您的IP一段时间以防止黑客入侵.如果你同意,你可以接受吗? (5认同)

Kar*_*arl 8

我只是遇到类似的问题,通过ssl在LINUX服务器上调用REST服务.在尝试了许多不同的配置方案后,我发现我必须在http头中发送一个UserAgent.

这是我调用REST API的最终方法.

        private static string RunWebRequest(string url, string json)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        // Header
        request.ContentType = "application/json";
        request.Method = "POST";
        request.AllowAutoRedirect = false;
        request.KeepAlive = false;
        request.Timeout = 30000;
        request.ReadWriteTimeout = 30000;
        request.UserAgent = "test.net";
        request.Accept = "application/json";
        request.ProtocolVersion = HttpVersion.Version11;
        request.Headers.Add("Accept-Language","de_DE");
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        byte[] bytes = Encoding.UTF8.GetBytes(json);
        request.ContentLength = bytes.Length;
        using (var writer = request.GetRequestStream())
        {
            writer.Write(bytes, 0, bytes.Length);
            writer.Flush();
            writer.Close();
        }

        var httpResponse = (HttpWebResponse)request.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var jsonReturn = streamReader.ReadToEnd();
            return jsonReturn;
        }
    }
Run Code Online (Sandbox Code Playgroud)