GetRequestStream()在将数据发布到HTTPS url时抛出超时异常

本文关键字:url HTTPS 异常 超时 数据 GetRequestStream | 更新日期: 2023-09-27 18:27:23

我正在调用托管在Apache服务器上的API来发布数据。我使用HttpWebRequest在C#中执行POST。

API在服务器上具有正常的HTTP和安全层(HTTPS)端口。当我调用HTTP URL时,它运行得非常好。但是,当我调用HTTPS时,它会给我超时异常(在GetRequestStream()函数处)。有什么见解吗?我使用的是VS 2010、.Net framework 3.5和C#。这是代码块:

string json_value = jsonSerializer.Serialize(data);

        HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com");
        request.Method = "POST";
        request.ProtocolVersion = System.Net.HttpVersion.Version10;
        request.ContentType = "application/x-www-form-urlencoded";
        byte[] buffer = Encoding.ASCII.GetBytes(json_value);
        request.ContentLength = buffer.Length;
        System.IO.Stream reqStream = request.GetRequestStream();
        reqStream.Write(buffer, 0, buffer.Length);
        reqStream.Close();

编辑:彼得建议的控制台程序运行良好。但当我添加需要发布到API的数据(JSON格式)时,它会抛出操作超时异常。以下是我添加到基于控制台的应用程序中的代码,它会引发错误。

byte[] buffer = Encoding.ASCII.GetBytes(json_value);
request.ContentLength = buffer.Length;

GetRequestStream()在将数据发布到HTTPS url时抛出超时异常

我遇到了同样的问题。这似乎对我来说已经解决了。我仔细检查了所有的代码,确保为我的所有HttpWebResponse对象调用webResponse.Close()和/或responseStream.Close()文档指出您可以关闭流或HttpWebResponse对象。两者兼而有之,所以我做到了。不关闭响应可能会导致应用程序耗尽可重用的连接,据我在代码中观察到的,这似乎会影响HttpWebRequest.GetRequestStream。

我不知道这是否会帮助您解决特定的问题,但您应该考虑在完成这些对象后处理它们。我最近做了一些类似的事情,用语句结束这些事情似乎为我清理了一堆超时异常

            using (var reqStream = request.GetRequestStream())
            {
                if (reqStream == null)
                {
                    return;
                }
              //do whatever
            }

也检查这些东西

  • 服务器是否在您的本地开发环境中提供https服务
  • 您是否正确设置了绑定*.443(https)
  • 您需要在请求中设置凭据吗
  • 是您的应用程序池帐户访问https资源,还是您的帐户正在被传递
  • 你有没有想过改用WebClient?

    using (WebClient client = new WebClient())
        {               
            using (Stream stream = client.OpenRead("https://server-url-xxxx.com"))
            using (StreamReader reader = new StreamReader(stream))
            {
                MessageBox.Show(reader.ReadToEnd());
            }
        }
    

编辑:

从控制台发出请求。

internal class Program
{
    private static void Main(string[] args)
    {
        new Program().Run();
        Console.ReadLine();
    }
    public void Run()
    {
       var request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com");
        request.Method = "POST";
        request.ProtocolVersion = System.Net.HttpVersion.Version10;
        request.ContentType = "application/x-www-form-urlencoded";
        using (var reqStream = request.GetRequestStream())
        {
            using(var response = new StreamReader(reqStream )
            {
              Console.WriteLine(response.ReadToEnd());
            }
        }
    }
}

试试这个:

    WebRequest req = WebRequest.Create("https://server-url-xxxx.com");
    req.Method = "POST";
    string json_value = jsonSerializer.Serialize(data); //Body data
    ServicePointManager.Expect100Continue = false;
    using (var streamWriter = new StreamWriter(req.GetRequestStream()))
    {
        streamWriter.Write(json_value);
        streamWriter.Flush();
        streamWriter.Close();
    }
    HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
    Stream GETResponseStream = resp.GetResponseStream();
    StreamReader sr = new StreamReader(GETResponseStream);
    var response = sr.ReadToEnd(); //Response
    resp.Close(); //Close response
    sr.Close(); //Close StreamReader

并查看URI:

  • 保留字符。发送保留字符的URI可以带来问题! * ' ( ) ; : @ & = + $ , / ? # [ ]

  • URI长度:不应超过2000个字符

我也遇到了这个问题。我想用控制台应用程序模拟数百名用户。当只模拟一个用户时,一切都很好。但随着用户数量的增加,Timeout异常一直存在。

发生超时是因为默认情况下ServicePoint(又名网站)的ConnectionLimit=2。非常好的阅读文章:https://venkateshnarayanan.wordpress.com/2013/04/17/httpwebrequest-reuse-of-tcp-connections/

你能做的是:

1) 在servicePoint中创建更多ConnectionGroups,因为ConnectionLimit是针对每个ConnectionGroups的。

2) 或者你只是简单地增加连接限制。

查看我的解决方案:

private HttpWebRequest CreateHttpWebRequest<U>(string userSessionID, string method, string fullUrl, U uploadData)
{
    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(fullUrl);
    req.Method = method; // GET PUT POST DELETE
    req.ConnectionGroupName = userSessionID;  // We make separate connection-groups for each user session. Within a group connections can be reused.
    req.ServicePoint.ConnectionLimit = 10;    // The default value of 2 within a ConnectionGroup caused me always a "Timeout exception" because a user's 1-3 concurrent WebRequests within a second.
    req.ServicePoint.MaxIdleTime = 5 * 1000;  // (5 sec) default was 100000 (100 sec).  Max idle time for a connection within a ConnectionGroup for reuse before closing
    Log("Statistics: The sum of connections of all connectiongroups within the ServicePoint: " + req.ServicePoint.CurrentConnections; // just for statistics
    if (uploadData != null)
    {
        req.ContentType = "application/json";
        SerializeToJson(uploadData, req.GetRequestStream());
    }
    return req;
}
/// <summary>Serializes and writes obj to the requestStream and closes the stream. Uses JSON serialization from System.Runtime.Serialization.</summary>        
public void SerializeToJson(object obj, Stream requestStream)
{
    DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
    json.WriteObject(requestStream, obj);            
    requestStream.Close();
}

您可能想要设置timeout属性,请在此处检查http://www.codeproject.com/Tips/69637/Setting-timeout-property-for-System-Net-WebClient