I am sending 100000 Requests and in order to check if all the requests has been sent successfully , I have developed a simple web page that counts the number of requests that has been sent.
The problem is this that the receiver counts less than 50000 and I also can not detect which one of them has been failed in order to send them again as the sender gets statusscode=OK for all of them and also no exception has detected.
I also tried it after removing webReq.Method="HEAD" but had no effect.
Any hints is appreciated.
Here is the sender's code:
try
{
var content = new MemoryStream();
var webReq = (HttpWebRequest)WebRequest.Create(url);
webReq.Method = "HEAD";
using (WebResponse response = await webReq.GetResponseAsync())
{
HttpWebResponse res = (HttpWebResponse)response;
if (res.StatusCode != HttpStatusCode.OK)
{
UnsuccessfulURLsPhase1.Add(url);
}
}
}
catch (Exception e)
{
UnsuccessfulURLsPhase1.Add(url);
}
This is receiver's code:
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
counter1++;
txtCounter.Text = counter1.ToString();
}
}
catch (Exception ex)
{
Debug.WriteLine("\nException raised!");
Debug.WriteLine("Source :{0} ", ex.Source);
Debug.WriteLine("Message :{0} ", ex.Message);
}
}
You're sending these out as quickly as possible? IANA suggests (and recent editions of Windows respect) using the range 49152 to 65535 for ephemeral ports, which are ports that are reserved to receive the reply from IP socket connections. This means that there are 16383 ports available, each of which must be left in a TIME_WAIT state for (IIRC) 120 seconds after the connection is closed.
In perfect conditions (and with routing equipment that can sustain thousands of simultaneous connections... a cheap SOHO router will probably overheat and become unreliable as it runs out of memory), you're going to be limited to a maximum of around 16000 requests every two minutes.
In practice, HttpWebRequest (and therefore WebClient) will maintain only a specific number of connections to a specific host, and pipeline requests over those connections, so without tweaking ServicePointManager, or the ServicePoint associated with the host you're trying to hit, you're going to have an awful amount of queueing to squeeze 100000 requests through these connections. It's likely that you'll hit timeouts somewhere down this path.
Your Page_Load is swallowing the exceptions so the server is always returning 200, OK.
You have to let the exception be thrown or you have to explicitly set the response status when an error occurs.
Found in here How to send a Status Code 500 in ASP.Net and still write to the response?
that TrySkipIisCustomErrors should be set.
Something like
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
counter1++;
txtCounter.Text = counter1.ToString();
}
}
catch (Exception ex)
{
Debug.WriteLine("\nException raised!");
Debug.WriteLine("Source :{0} ", ex.Source);
Debug.WriteLine("Message :{0} ", ex.Message);
// Raise the exception
// throw;
// or assign the correct status and status code
Response.Clear();
Response.TrySkipIisCustomErrors = true
Response.ContentType = "text/plain";
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Response.Write(ex.Message);
// Send the output to the client.
Response.Flush();
}
}
(Hope it helps, its been a long time since I have done something in WebForms :S )
Related
First of all, thanks for the help you can give me.
Okay, first, excuse my little knowledge, I'm learning, so forgive my ignorance.
I have a method that calls a service, and it is assumed that if any response other than the range of 200 is received, it goes to catch. Well, I need, within that catch, to retrieve from the header (or somewhere) of that response the time it took the service to respond.
I can't use timer or things like that (it was what I first thought of).
The thing is, I don't know how to recover this data from the exception.
Thank you very much!
{
try
{
// Reading the http response
using (HttpWebResponse webResponse = httpWebRequest.GetResponse () as HttpWebResponse)
{
///// Call to endpoint
}
}
catch (WebException ex)
{
//// Here I need to retrieve the time it took for the service to respond (with the error)
}
return response;
} ```
Adding an example to what kshkarin mentioned:
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
var request = WebRequest.Create("http://www.google.com");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream answer = response.GetResponseStream())
{
// do something
watch.Stop();
Console.WriteLine($"Success at {watch.ElapsedMilliseconds}");
}
}
}
catch (WebException e)
{
// If we got here, it was a timeout exception.
watch.Stop();
Console.WriteLine($"Error occurred at {watch.ElapsedMilliseconds} \n {e}");
}
Indeed you must be set timeout in web request and check this with TimeoutException
if you have some scenario you can check this with simple DateTime
set DateTime.Now and get distance time
I am currently working on an UWP app, that will run on a Raspberry PI. Most of my application can be used without an internet connection, but parts of it rely on fetching data from a server ran locally.
My issue is that whenever the server is offline, I can not handle the exceptions raised by the HttpClient.
To avoid using async tasks in the constructor of the ViewModel, I've moved it to the OnLoaded method of the View.
These are the methods that I use:
HomeAssistantView
private async void OnLoaded(object sender, RoutedEventArgs e)
{
await ViewModel.LoadEntities();
}
HomeAssistantViewModel
public async Task LoadEntities()
{
var entityList = await _homeAssistantService.LoadEntities();
Switches = new ObservableCollection<HomeAssistantSwitchEntity>(entityList.OfType<HomeAssistantSwitchEntity>());
Entities = new ObservableCollection<HomeAssistantEntity>(entityList.Where(entity =>!(entity is HomeAssistantSwitchEntity)));
}
HomeAssistantService
public async Task<List<HomeAssistantEntity>> LoadEntities()
{
_client.BaseAddress = new Uri(_homeAssistantURL);
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_homeAssistantToken}");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = await _client.GetAsync("api/states");
if (response.IsSuccessStatusCode)
{
return DeserializeConfigFile(await response.Content.ReadAsStringAsync());
}
}
catch (HttpRequestException e)
{
Debug.WriteLine(e.Message);
}
return new List<HomeAssistantEntity>();
}
Even though I've added a try block, the application raises a System.Exception, with the message "The server name or address could not be resolved". After disabling the generic Exception type in the settings, Visual Studio told me it was a type of HttpRequestException with the message An error occurred while sending the request.
In a different part of my application, where I use a weather API, I got away with using the NetworkInformation.GetInternetConnectionProfile() to check whether there is an internet connection available prior to sending a request, but it's not a viable option here. Also, I've thought of sending a ping to the server prior to trying to fetch the data, but as far as I'm concerned, pinging is not available on the Windows 10 IoT Core.
I understood, that, you don't want the exception to be thrown, is this correct?
If yes just replace
catch (HttpRequestException e)
{
Debug.WriteLine(e.Message);
}
with
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
this will catch all occuring exceptions
I have webserver receive data by async sockets:
var e = new SocketAsyncEventArgs();
e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed);
while (true)
{ allDone.Reset();
mySocket.AcceptAsync(e);
allDone.WaitOne();
}
and the other method:
public void e_Completed(object sender, SocketAsyncEventArgs e)
{
var socket = (Socket)sender;
ThreadPool.QueueUserWorkItem(handleTcpRequest, e.AcceptSocket);
e.AcceptSocket = null;
socket.AcceptAsync(e);
}
this is the handleTcpRequest method.in this part I receive data from socket and do operation:
public void handleTcpRequest(object state)
{
string sBuffer = "";
string BufferTotal = "";
byte[] secureMessage;
Byte[] bReceive = new Byte[1024];
var mySocket = (Socket)state;
do
{
try
{
firstBufferRead = mySocket.Receive(bReceive, bReceive.Length, 0);
}
catch (Exception ex)
{
Console.WriteLine("Error Occurred (:))) " + ex.Message);
}
sBuffer += Encoding.GetEncoding(1252).GetString(bReceive, 0, firstBufferRead);
BufferTotal += Encoding.UTF8.GetString(bReceive, 0, firstBufferRead);
} while (mySocket.Available != 0);
.
.
.
.
mySocket.Close();
}
whats wrong?
sometimes connection resets and closes. this happens when distance is far or post data not multipart. but in multipart happens rarely. more with forms not in multipart.
when and where should I close socket?
when I work with socket in handleTcpRequest method its local. isn't it correct? I can't find the origin of the problem
The only way to know that you've received everything in a HTTP request is to understand the HTTP request. And to understand a HTTP request you have to choices:
Use a complete HTTP server
Create a HTTP parser
The reason to why your code fails for multi-part data is probably because the other party sends one part at a time, which means that your code manages to do a mySocket.Available != 0 before the rest is sent.
If you want to do the latter you have to read the HTTP header (in format headerName: headervalue, do note that there are also white space rules that you have to consider). Search for a header named content-length, parse it's value as an integer. Then wait for two line feeds in a row (\r\n\r\n). Finally start count bytes until you have received the number of bytes that was specified in the content-length header.
ohh.. ony more thing.. pray to God that Transfer-Encoding: Chunkedis not used.
My advice is that you give up on using sockets directly as it's apparent that you don't understand how they work or how to do research on them.
If response has a header of Connection: Close, then the socket closes automatically.
I have a server/client type app, Wireshark shows that the client has sent a packet to the server, the server had given the expected response but shows a ICMP Destination port unreachable error.
I'm using a function that was on the MDSN website which has worked for me before.
EDIT: To update I have checked that the packet is being sent after the phone has started listening, I have tried other ports. There is no socket exception so i'm just looking for the best way to go about debugging network errors.
Any ideas?
public string Receive()
{
string response = "Operation Timeout";
// We are receiving over an established socket connection
if (udpSocket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = new DnsEndPoint(SERVER, RECIVEPORT);
// Setup the buffer to receive the data
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
// Inline event handler for the Completed event.
// Note: This even handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// Retrieve the data from the buffer
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
_clientDone.Set();
});
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Receive request over the socket
Debug.WriteLine("Listening now:" + DateTime.Now.Second + ":" + DateTime.Now.Millisecond);
try
{
Debug.WriteLine("No socket exception");
udpSocket.ReceiveFromAsync(socketEventArg);
}
catch (SocketException e)
{
Debug.WriteLine(e.SocketErrorCode);
}
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}
"ICMP Destination port unreachable" means that there was no application bound to the port you were sending to. Make sure that your sendto() is targeting to correct IP address and port number. Also check that your listener is calling bind() on INADDR_ANY and the correct port. A common mistake is to forget to convert the port number to network byte order (big-endian). See htons().
I am kicking off parameterized Jenkins builds from a c# application.
The urls are valid (I can pull it from the log and run it with no issue). At certain points all webrequests will time out, no matter how much the timeout is set for (i've gone up to 90 seconds) or how many times it is run.
This is intermittant and certain times, I will have no issues at all.
while (count<5)
{ try{
log.WriteEntry("RunningJenkinsBuild- buildURL=" + buildUrl, EventLogEntryType.Information);
WebRequest request = WebRequest.Create(buildUrl);
request.GetResponse();
return;
}
catch (WebException ex)
{
log.WriteEntry("Timeout- wait 15 seconds and try again-"+ex.Message, EventLogEntryType.Error);
Thread.Sleep(15000);
count++;
}
catch (Exception ex2)
{
log.WriteEntry(ex2.Message, EventLogEntryType.Error);
return;
}
}
This cleared it up. 'Using' helped it out.
WebRequest request = WebRequest.Create(buildUrl);
request.Timeout = 10000;
using (WebResponse response = request.GetResponse()) { }
Thread.Sleep(5000);