?
Solved

WebException thrown on a HttpWebRequest.GetResponse() call

Posted on 2005-04-05
10
Medium Priority
?
1,436 Views
Last Modified: 2008-01-16
Hi,

I have a problem using HttpWebRequest class.
I create an application, which communicates with a network device (not a PC), which has a built in HTTP 1.1 server listening on port 80. For some requests, which I send to the server it answers with a short byte sequence:

HTTP/1.1 200 OK\r\n

and that's it, no more data (I check network traffic using Ethereal network monitor).
In case of such response from the server, I get a WebException on a call to HttWebRequest.GetResponse() method saying: "The underlying connection was closed: An unexpected error occured on a receive". If there are some data coming from server, then GetResponse() method returns instance of HttpWebResponse properly.

here is a code, where I get a WebException:

HttpWebRequest hwr = (HttpWebRequest) WebRequest.Create(TargetUriString);
hwr.Timeout = 10000;
hwr.Method = "POST";
hwr.UserAgent = "AddressEditor";
hwr.ContentLength = buf.Length;
hwr.KeepAlive = true;
HttpWebResponse hwResponse = null;
Stream sr = null;
try
{
        // Write data
      Stream s = hwr.GetRequestStream();
      s.Write(buf,0,buf.Length);
      s.Close();
      // Read response
      hwResponse = (HttpWebResponse) hwr.GetResponse();     // WebException is thrown here !!!
      if(hwResponse.StatusCode == HttpStatusCode.OK)
      {
            if(hwr.HaveResponse)
            {
                  sr = hwResponse.GetResponseStream();
                  int offset=0;
                  int remaining = buf.Length;
                  while (remaining > 0)
                  {
                        int read = sr.Read(buf, offset, remaining);
                        if (read <= 0)
                              break;
                        remaining -= read;
                        offset += read;
                  }
            }
      }
}
catch(WebException we)
{
      Console.WriteLine(we.Message);
}
finally
{
      if(sr != null)
            sr.Close();
      if(hwResponse != null)
            hwResponse.Close();
}

Actually, I am not completely sure, whether the problem is im my code, .NET framework or device HTTP server, because exception occurs immediately after a call to GetResponse() and the device usually answers with "HTTP/1.1 200 OK\r\n" after a approximately 5 seconds timeout, because of processing of input data. So the GetResponse() does not wait for response and just throws exception. It does not happen with this code when the server returns some data.
Could you please give me a hint:
1) Am I correctly using HttpWebrequest to write data to the remote server?
2) How to make my code block and wait untill "HTTP/1.1 200 OK\r\n" response comes from the server? (The server becomes unavailable untill it processes all input data sent by me and I can not send next requests to it untill this one ends with 200 OK)

Thank you for any help, it is really apreciated.

Sergey
0
Comment
Question by:Rothmans
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
10 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 13706413
Are you communicating with your own server, or someone else's?

Bob
0
 

Author Comment

by:Rothmans
ID: 13706636
The server in the device is written not by me and I have almost no information describing it's behaviour and no access to the code.

Sergey.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 13706690
Well, it sounds like you are not forming the WebRequest correctly, and unless you can find the right format, then it will be virtually impossible to fix.

You did say that you are getting some requests back successfully.  What is different between the requests that succeed and the ones that fail?

Bob
0
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 

Author Comment

by:Rothmans
ID: 13706962
Well, there are two entry points for me in the device HTTP server:
1) /cgi-bin/get.cgi
This script (?) returns data describing device settings
2) /cgi-bin/set.cgi
This script accepts settings (same as for get.cgi), which I (user) want to propagate to the device

Format of request to the first script is:
<method POST>
<HTTP Headers>
User-Agent: <user agent name>
Content-Length: <length of >
\r\n
<binary data defining settings, which I want to retireve>
<two trailing zeros>
Server response for this case is:
HTTP/1.1 200 OK\r\n
\r\n
<binary data describing device settings>
<two trailing zeros>

Format of request to the second script is:
<method POST>
<HTTP Headers>
User-Agent: <user agent name>
Content-Length: <length of >
\r\n
<binary data describing settings, which I want to set>
<two trailing zeros>
Server response for this case is:
HTTP/1.1 200 OK\r\n

I use the same code (see above) for both cases.
For the first case GetResponse() returns HttpResponse instance, from where I can get response binary data, properly, no exception is thrown.

For the second case settings ARE ACCEPTED by the device and ARE PROCESSED properly, but GetResponse throws mentioned above exception.

Of course, I could just ignore this exception, because I do not need actually response data, but...
I need to send several requests of second type to the device in order to complete my task.
It happens that the device processes input data several seconds and during this period device is unavailable. Any attempt to establish HTTP connection to it fails with HTTP server response "503 Service Unavailable". Therefore, I can not proceed with next requests.
That's why I acctually need to know when the device finishes accepting and processing input data (returning 200 OK Status Line), because otherwise next calls will fail and timeouts (how much time the device needs to process data) are undefined and may vary.

PS: It seems that "Expect: 100-Continue" mode is not supported by the device HTTP server.
0
 

Author Comment

by:Rothmans
ID: 13707122
After some reading HTTP RFC I came to one suspicion.
RFC says that in case when there is no data returned by the server the response should be "204 No Content".
Could it be that GetResponse waits for a data because "200 OK" response acquired and for the second described scenario "200 OK" is not the right answer because there are no data following this response?
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 250 total points
ID: 13707139
If I am understanding what you have so thoroughly described, then my first take is to wrap the WebRequest with Try...Catch blocks, and handle the error, but don't do anything.

Bob
0
 

Author Comment

by:Rothmans
ID: 13707279
That would be a solution if I would not need to make several requests one after another.
If I put WebRequest into try&catch block, then the next request will fail because device is busy.

Sergey
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 13707333
I mean something like this:

HttpWebRequest hwr = (HttpWebRequest) WebRequest.Create(TargetUriString);
hwr.Timeout = 10000;
hwr.Method = "POST";
hwr.UserAgent = "AddressEditor";
hwr.ContentLength = buf.Length;
hwr.KeepAlive = true;
HttpWebResponse hwResponse = null;
Stream sr = null;
try
{
        // Write data
     Stream s = hwr.GetRequestStream();
     s.Write(buf,0,buf.Length);
     s.Close();
     // Read response

    try {
         hwResponse = (HttpWebResponse) hwr.GetResponse();     // WebException is thrown here !!!
    }
    catch {}

     if(hwResponse.StatusCode == HttpStatusCode.OK)
     {
          if(hwr.HaveResponse)
          {
               sr = hwResponse.GetResponseStream();
               int offset=0;
               int remaining = buf.Length;
               while (remaining > 0)
               {
                    int read = sr.Read(buf, offset, remaining);
                    if (read <= 0)
                         break;
                    remaining -= read;
                    offset += read;
               }
          }
     }
}
catch(WebException we)
{
     Console.WriteLine(we.Message);
}
finally
{
     if(sr != null)
          sr.Close();
     if(hwResponse != null)
          hwResponse.Close();
}


Bob
0
 

Author Comment

by:Rothmans
ID: 13707356
Anyway thank you for a hint.
I try now to catch "503 Service Unavailable" response and repeat a request attempt in this case. Seems it is possible.

Sergey.
0
 

Author Comment

by:Rothmans
ID: 13707786
I succeeded to avoid the problem handling "503 Service Unavaible" response.
Thenk you, Bob, for your help.

Sergey.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question