HttpWebRequest, POST, keep-alive and others...

G

Guest

The following code being repeated in a loop sends keep-alive at frst
iteration only.
So I quickly run out of ports (all are in time_wait state)
Why?

// create the web request to get the remote stream
HttpWebRequest requestToCrk = (HttpWebRequest)WebRequest.Create( url );
requestToCrk.Method = "POST";
requestToCrk.KeepAlive = true;
requestToCrk.ContentType = "application/octet-stream";
requestToCrk.ContentLength = buff.Length;

Stream sendStream = requestToCrk.GetRequestStream();
sendStream.Write(buff, 0, bytes ); // real writing to web server !!!
sendStream.Close();

HttpWebResponse responseFromCrk;
try
{
responseFromCrk = (HttpWebResponse)requestToCrk.GetResponse();
StreamReader sr = new StreamReader(
responseFromCrk.GetResponseStream() );
responseBody = sr.ReadToEnd();
}
catch(System.Net.WebException we)
{
ProcessError( we, "pbviews connection manager is not running." );
return;
}
 
N

Nicholas Paldino [.NET/C# MVP]

VladG,

I don't see calls to Close/IDisposable.Dispose on the response stream or
the response returned from GetResponse. You should probably have your code
look like this:

// create the web request to get the remote stream
HttpWebRequest requestToCrk = (HttpWebRequest)WebRequest.Create( url );
requestToCrk.Method = "POST";
requestToCrk.KeepAlive = true;
requestToCrk.ContentType = "application/octet-stream";
requestToCrk.ContentLength = buff.Length;

// Use using to make sure the stream is disposed of.
using (Stream sendStream = requestToCrk.GetRequestStream())
{
sendStream.Write(buff, 0, bytes ); // real writing to web server !!!
sendStream.Close();
}

HttpWebResponse responseFromCrk;
try
{
using (responseFromCrk = (HttpWebResponse)requestToCrk.GetResponse())
using (StreamReader sr = new
StreamReader(responseFromCrk.GetResponseStream())
{
responseBody = sr.ReadToEnd();
}
}
catch(System.Net.WebException we)
{
ProcessError( we, "pbviews connection manager is not running." );
return;
}

This will result in the resources being cleaned up correctly, and you
probably won't run out of ports.

Hope this helps.
 
G

Guest

Nicholas Paldino said:
I don't see calls to Close/IDisposable.Dispose on the response stream or
the response returned from GetResponse. You should probably have your code
look like this:

Thank you for quick response. Unfortunately, it did not help.
At server side the request still comes with header "Connection: Close"
 
J

Joerg Jooss

VladG said:
Thank you for quick response. Unfortunately, it did not help.
At server side the request still comes with header "Connection: Close"

The Connection header is a hop-by-hop header. Are you testing this on
the Internet or on a LAN?

Cheers,
 
G

Guest

The Connection header is a hop-by-hop header. Are you testing this on
the Internet or on a LAN?

At one mashine. Web server is Indy http server. So I can see that
"Connection" header arrives with "Close".
I just wonder, if I recreate HttpWebRequest each iteration in the loop, who
can maintain the connection from iteration to iteration?
 
J

Joerg Jooss

VladG said:
At one mashine. Web server is Indy http server. So I can see that
"Connection" header arrives with "Close".
I just wonder, if I recreate HttpWebRequest each iteration in the
loop, who can maintain the connection from iteration to iteration?

There's no 1:1 relationship between WebRequests and TCP connections.
TCP connection management is handled by the BCL under the hood, and it
is only partially exposed to user code through the ServicePoint und
ServicePointManager classes.

These classes also assure you adhere to HTTP 1.1 recommendations by
default -- which means you should not create more than two persistent
connections to any HTTP server. You can overrule this behaviour by
setting ServicePointManager.DefaultPersistentConnectionLimit to a value
greater than two. You should only do that in your own environment,
though. Opening dozens of persistent connections from the same source
IP might be considered a DoS attack.

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top