HttpWebRequest getRequestStream зависает на нескольких прогонах

Я написал код для отправки и чтения текста из прослушивателя. Это отлично работает на 1-м и 2-м обмене, но на 3-м посылает туда длительную задержку между вызовом GetRequestStream и фактической записью данных.

Я выбрал выходной поток на стороне отправки, а также считыватель потока и поток ввода на стороне чтения, как рекомендовано здесь: Кто-нибудь знает, почему я получаю HttpWebRequest Timeout?

и он по-прежнему висит на третьей попытке отправить информацию. Кажется, он определенно висит на GetRequestStrean в sendMessage:

public void sendMessage(string message)
{
    HttpWebRequest request;
    string sendUrl;

    sendUrl = "http://" + termIPAddress + ":" + sendPort + "/";
    Uri uri = new Uri(sendUrl);
    Console.WriteLine("http://" + termIPAddress + ":" + sendPort + "/");

    ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri);
    servicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);
    servicePoint.ConnectionLeaseTimeout = 300;


    request = (HttpWebRequest)WebRequest.Create(sendUrl);
    request.KeepAlive = false;
    request.Method = "POST";
    request.ProtocolVersion = HttpVersion.Version11;
    request.ContentType = "application/x-www-form-urlencoded";
    request.Headers.Add("SourceIP", localIPAddress);
    request.Headers.Add("MachineName", localName);
    requestStarted = true;


    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message);
    request.ContentLength = buffer.Length;
    try
    {
        using (Stream output = request.GetRequestStream())
        {
            output.Write(buffer, 0, buffer.Length);
            output.Close();
            request = null;
        }
    }
    catch(WebException wE)
    {
        Console.WriteLine(wE.Message);
    }
}

И это часть чтения:

public string getMessage()
{
    Console.WriteLine("Entering actual listener");
    string s;
    string sourceIP;

    NameValueCollection headerList;

    HttpListenerContext context = terminalListener.GetContext();
    HttpListenerRequest request = context.Request;

    headerList = request.Headers;
    sourceIP = headerList.GetValues("SourceIP")[0];
    termName = headerList.GetValues("MachineName")[0];
    termIPAddress = sourceIP;
    using (System.IO.Stream body = request.InputStream)
    {
        System.Text.Encoding encoding = request.ContentEncoding;
        using (System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding))
        {
            s = reader.ReadToEnd();
            body.Close();
            reader.Close();
        }
    }

    return termName + " : " + s;    
}

Я также попытался добавить привязку конечной точки IP, но должен быть честным, я не полностью понимаю этот фрагмент кода:

private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
    int portNumber = Convert.ToInt32(sendPort);
    IPEndPoint IEP = new IPEndPoint(IPAddress.Parse(localIPAddress), 0); 
    Console.WriteLine(Convert.ToString(IEP));
    return IEP;  
}

Любая помощь очень ценится.

Ответ 1

Вы просто забыли называть HttpWebRequest.GetResponse и, следовательно, лишены ограничения на соединение.

Итак, вы должны изменить свой код следующим образом:

try
{
    using (Stream output = request.GetRequestStream())
        output.Write(buffer, 0, buffer.Length);

    var response = request.GetResponse() as HttpWebResponse;
    //TODO: check response.StatusCode, etc.
}
catch(WebException wE)
{
    Console.WriteLine(wE.Message);
}

Кроме того, в некоторых случаях вам может потребоваться настроить ограничение по умолчанию для подключения: ServicePointManager.DefaultConnectionLimit

Или используйте постоянные подключения: HttpWebRequest.KeepAlive