I'm pretty newbie of C# programming and I'm trying to understand how to optimize this piece of code that is called always into a thread to grab image (snapshot) form an IP camera. I'm trying to make some optimization to make faster the HTTP request but I can't see how and where act. May I ask to experts if there is a way to get this result? Thank you.
private Image GetImage()
{
HttpWebRequest req = null;
Image img = null;
HttpWebResponse res = null;
try
{
req = WebRequest.Create(_httpCommand) as HttpWebRequest;
req.Method = "GET";
req.PreAuthenticate = true;
req.AllowWriteStreamBuffering = true;
req.Credentials = new NetworkCredential(_user, _pwd);
res = req.GetResponse() as HttpWebResponse;
using (Stream rs = res.GetResponseStream())
{
img = new Bitmap(rs);
}
}
catch (Exception e) {
_status = false; //<<------------------Signaling the FAILURE status! ---
if (img != null)
img.Dispose(); //<< for ------GC--------------
//insert in LOG
Log logItem = new Log(DateTime.Now, e.Message);
AddLogItem(logItem);
}
return img;
}
I remember, that HttpWebRequest will try to determine proxy settings automatically, which takes time.
req.Proxy = GlobalProxySelection.GetEmptyWebProxy();
tells it to not use any proxy, thus searching for the correct setting will be skipped.
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.proxy%28v=vs.110%29.aspx
Related
I have the following code:
string url = string.Format("http://{0}:{1}/{2}/xml",Address.Host,Address.Port,Address.ContextRoot);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.UserAgent = "Foo";
req.ContentType = "text/xml; charset=\"UTF-8\"";
req.KeepAlive = false;
using (Stream reqStream = req.GetRequestStream())
{
SoapEnvelope s = new SoapEnvelope(Address, null);
XmlDocument xmlDoc = s.GenerateXml(message);
xmlDoc.Save(reqStream);
}
result = ReceiveAnswer(req);
private string ReceiveAnswer(HttpWebRequest req)
{
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
using (Stream resStream = res.GetResponseStream())
using (StreamReader reader = new StreamReader(resStream))
{
if (res.StatusCode != HttpStatusCode.OK)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Failed to post data to http://{0}:{1}", Address.Host, Address.Port).AppendLine();
sb.AppendFormat("Response: {0} {1}", res.StatusCode, res.StatusDescription);
res.Close();
throw new WebException(sb.ToString());
}
String resData = reader.ReadToEnd();
return resData;
}
}
This code works fine, when I'm connecting to an existing server, but I've just tested, that if the server I specify does not exist then this part: (HttpWebResponse)req.GetResponse() will hang. I expected to get a webexception or something in this scenario, because I want to catch it.
I've read it somewhere that this Response has a timeout of 100 seconds, I've waited more than that, but nothing happened. Then I set the Timeout property to 15 seconds, but that didn't help either.
Anyone knows what should I do?
There was no problem with my code, an other part of the company's code causes the problem.
Be very careful with what you're doing.
Timeout method does not apply to the time waiting for the response to be caught.
Timeout counts for the entire life of your connection (meaning request + response).
If you're then setting a too-low timeout time, your program will never catch it. Maybe you could try to raise the Timeout number?
Iam trying to write a code, which will connect to IP camera and get a jpeg image from it. It goes like this:
HttpWebRequest request;
CookieContainer cookies= new CookieContainer();
//First, I log to IP camera on adress http://192.168.0.2
request = (HttpWebRequest)WebRequest.Create(new Uri(sanyoUrls[0]));
request.Credentials = new NetworkCredential(username, password);
request.KeepAlive = false;
request.AllowAutoRedirect = false;
request.CookieContainer = cookies;
// then I try to get the IP camera jpeg image from adress http://192.168.0.2/liveimg.cgi
cookies = request.CookieContainer;
request = (HttpWebRequest)WebRequest.Create(new Uri(sanyoUrls[1]));
request.KeepAlive = false;
request.Credentials = new NetworkCredential(username, password);
request.AllowAutoRedirect = false;
request.CookieContainer = cookies;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream strImg = response.GetResponseStream())
{
MemoryStream memStr = new MemoryStream();
strImg.CopyTo(memStr);
if (response.ContentType == "application/xml")
{
// write message to GUI
}
else
{
try
{
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(memStr);
PBcameraImage.Image = bmp;
// write OK to file
}
catch (ArgumentException ex)
{
// write NULL to file
}
}
}
response.Close();
}
This code is executed with specified period (I tried 40 ms up to 1 seconds). And the log in the file looks usually like this:
First is NULL, then 20 times OK, and after it are in the file only NULLs with some exception of single OK line after long time. So I get only 20 pictures from IP camera. Any advices? Thank you.
Cheers,
Ondrej
I am working on a desktop application developed in C# (.NET environment).
This application connects to remote server using HttpWebRequest. If due to any reason my PC is disconnected from the internet and I re-connect it my application always gives request timeout for HttpWebRequest until I restart my whole application and if I again add new thread to my application after network d/c it works fine.
Is there any way to reset my network or anyone can tell me how does it work?
//my code is..
public String request(String add, String post, int time, String reff, int id, int rwtime)
{
try
{
if (rwtime == 0)
{
rwtime = 100000;
}
string result = "";
string location = "";
// Create the web request
HttpWebRequest req = WebRequest.Create(add) as HttpWebRequest;
req.ReadWriteTimeout = rwtime;
req.KeepAlive = true;
req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
req.Accept = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
req.ContentType = "application/x-www-form-urlencoded";
req.Timeout = time;
req.Referer = reff;
req.AllowAutoRedirect = false;
req.CookieContainer = statictk.cc[id];
req.PreAuthenticate = true;
if (post != "")
{
req.Method = "POST";
string postData = post;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte1 = encoding.GetBytes(postData);
// Set the content type of the data being posted.
req.ContentType = "application/x-www-form-urlencoded";
// Set the content length of the string being posted.
req.ContentLength = byte1.Length;
Stream newStream = req.GetRequestStream();
newStream.Write(byte1, 0, byte1.Length);
newStream.Close();
}
else
{
req.Method = "GET";
}
// Get response
try
{
HttpWebResponse response = req.GetResponse() as HttpWebResponse;
// Get the response stream
location = response.GetResponseHeader("Location");
if (location == "")
{
Stream responseStream = response.GetResponseStream();
if (response.ContentEncoding.ToLower().Contains("gzip"))
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
else if (response.ContentEncoding.ToLower().Contains("deflate"))
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
StreamReader reader = new StreamReader(responseStream, Encoding.Default);
// Read the whole contents and return as a string
result = reader.ReadToEnd();
}
else
{
result = location;
}
response.Close();
if (result == "") result = "retry";
return result;
}
catch (Exception e)
{
log.store("errorinresponce", e.Message);
if (statictd.status[id] != "removed")
{
return "retry";
}
else
{
return "error";
}
}
}
catch(Exception f)
{
log.store("Networkerrorretry", f.Message);
if (f.Message == "The operation has timed out")
{
return "retry";
}
string ans = MessageBox.Show("There was a Network Error..Wish to Retry ?\nError msg : "+ f.Message, "Title", MessageBoxButtons.YesNo).ToString();
if (ans == "Yes")
return "retry";
else
{
Invoketk.settxt(id, "Not Ready");
return "error";
}
}
}
It sounds like your application is missing some error handling. A disconnect can happen at any time and your application should be able to handle it. Try to surround the network loop with a try-catch statement, and then catch for the different kinds of exceptions. Depending on what exception was thrown, you can then decide if you reconnect to the server silently or if you want to generate an error message.
I was trying to use httpwebrequest to use a rest like service on a remote server and from the first execution itself, my code was hanging the program. Then I tried it as a console application to make sure it has nothing to do with the program itself but no luck!
string credentialsJson = #"{""username"":""test"",
""password"":""test""
}";
int tmp = ServicePointManager.DefaultConnectionLimit;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(#"https://qrua.com/qr/service" + #"/auth/login");
request.Method = "POST";
request.KeepAlive = true;
request.Timeout = 50000 ;
request.CookieContainer = new CookieContainer();
request.ContentType = "application/json";
try
{
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(credentialsJson);
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION:" + e.Message);
}
//WebResponse response = request.GetResponse();
try
{
using (WebResponse response = (HttpWebResponse)request.GetResponse())
{
Console.WriteLine("request:\n" + request.ToString() + "\nresponse:\n" + response.ContentLength);
response.Close();
}
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION: in sending http request:" + " \nError message:" + e.Message);
}
Tried several things from different forums but it doesnt help. Even a simple console app with the above code hangs the console indefinitely! Any help would be great..
Thanks
You're never closing the StreamWriter... so I suspect it's not being flushed. Admittedly I'd expect an error from the server instead of just a hang, but it's worth looking at.
Btw, you don't need to close the response and dispose it. Just the using statement is enough.
There's not much you can do if the remote server is not responding other than defining a Timeout and catch the exception as you did in order to inform the user that the operation cannot complete because the remote site didn't respond:
var request = (HttpWebRequest)WebRequest.Create("https://qrua.com/qr/service/auth/login");
request.Timeout = 5000;
// If the server doesn't respond within 5 seconds you might catch the timeout exception
using (var response = request.GetResponse())
{
}
If you don't want to freeze the UI you could use the async version: BeginGetResponse
Try specifying request.ContentLength.
Before doing:
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(credentialsJson);
Try something like this:
using (MemoryStream stream = new MemoryStream())
{
using (var writer = StreamWriter writer = new StreamWriter(stream))
{
writer.Write(credentialsJson);
writer.Close();
}
request.ContentLength = stream.Length;
}
I am using a WebRequest to check if a web page or media (image) exist. On GetResponse i get a System.Net.WebException exception. I ran through 100 links and it feels like its going slower then it should. Is there a way to not get this exception or handle this more gracefully?
static public bool CheckExist(string url)
{
HttpWebRequest wreq = null;
HttpWebResponse wresp = null;
bool ret = false;
try
{
wreq = (HttpWebRequest)WebRequest.Create(url);
wreq.KeepAlive = true;
wresp = (HttpWebResponse)wreq.GetResponse();
ret = true;
}
catch (System.Net.WebException)
{
}
finally
{
if (wresp != null)
wresp.Close();
}
return ret;
}
Try setting
wreq.Method = "Head";
after the "KeepAlive" line. If the webserver you are calling is smart enough, that will tell it not to return any body contents which should save some time.