I am sending a message to a server through HTTP 1.1. Everything sends correctly to the server or website I have chosen, but when I receive the response from the server/website and my sr.readToEnd() executes, it terminates.
I know that the message I have sent is correct, but I am trying to do a try-catch statement were if it terminates again, it will try to read another way. I am not sure how to do this and I was advised that I could use content-length (except I do not know how to do that either).
Here is what I have so far:
try
{ //Read server message
String response = sr.ReadToEnd();
}
catch
{ //If terminate occurs, read a different way
}
If I remove the try/catch blocks I see this:
Unhandled Exception: System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time..
I know it's pretty brief what I provided, but any methods to tackle this sort of problem I described?
I'd say in general you can do (as #joel recommended.
Or try whether catch when() works for you.
Example:
try
{
someCode();
}
catch (YourExpectedException ex) when (
someBooleanExpression
|| someOtherBooleanExpr
|| thirdBoolean)
{
/* this part runs when() YourExpectedException occurs *and*
one of those three hypothetical example expressions is True */
}
catch (YourExpectedException ex)
{
/* this part runs If YourExpectedException occurs and the previous
When() expression is *Not true */
Whatever();
} /* you can continue catching other expected exceptions
and when() combinations here.
And/Or perhaps say any other exception is unexpected and
will be handled by a higher-level:
*/
catch // any other Exception just to re-throw it back 'to-whom-it-may-concern':
throw;
See also Catching exceptions with "catch, when"
Related
My application is working as a client application for a bank server. The application is sending a request and getting a response from the bank. This application is normally working fine, but sometimes
The I/O operation has been aborted because of either a thread exit or
an application request
error with error code as 995 comes through.
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived",
ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.thisSocket.EndReceive(asyn); //Here error is coming
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
}
}
Once this error starts to come for all transactions after that same error begin to appear, so
please help me to sort out this problem. If possible then with some sample code
Regards,
Ashish Khandelwal
995 is an error reported by the IO Completion Port. The error comes since you try to continue read from the socket when it has most likely been closed.
Receiving 0 bytes from EndRecieve means that the socket has been closed, as does most exceptions that EndRecieve will throw.
You need to start dealing with those situations.
Never ever ignore exceptions, they are thrown for a reason.
Update
There is nothing that says that the server does anything wrong. A connection can be lost for a lot of reasons such as idle connection being closed by a switch/router/firewall, shaky network, bad cables etc.
What I'm saying is that you MUST handle disconnections. The proper way of doing so is to dispose the socket and try to connect a new one at certain intervals.
As for the receive callback a more proper way of handling it is something like this (semi pseudo code):
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived", ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket client = (SocketPacket)asyn.AsyncState;
int bytesReceived = client.thisSocket.EndReceive(asyn); //Here error is coming
if (bytesReceived == 0)
{
HandleDisconnect(client);
return;
}
}
catch (Exception err)
{
HandleDisconnect(client);
}
try
{
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
//do your handling here
}
catch (Exception err)
{
// Your logic threw an exception. handle it accordinhly
}
try
{
client.thisSocket.BeginRecieve(.. all parameters ..);
}
catch (Exception err)
{
HandleDisconnect(client);
}
}
the reason to why I'm using three catch blocks is simply because the logic for the middle one is different from the other two. Exceptions from BeginReceive/EndReceive usually indicates socket disconnection while exceptions from your logic should not stop the socket receiving.
In my case, the request was getting timed out. So all you need to do is to increase the time out while creating the HttpClient.
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(5);
I had the same issue with RS232 communication. The reason, is that your program executes much faster than the comport (or slow serial communication).
To fix it, I had to check if the IAsyncResult.IsCompleted==true. If not completed, then IAsyncResult.AsyncWaitHandle.WaitOne()
Like this :
Stream s = this.GetStream();
IAsyncResult ar = s.BeginWrite(data, 0, data.Length, SendAsync, state);
if (!ar.IsCompleted)
ar.AsyncWaitHandle.WaitOne();
Most of the time, ar.IsCompleted will be true.
I had this problem. I think that it was caused by the socket getting opened and no data arriving within a short time after the open. I was reading from a serial to ethernet box called a Devicemaster. I changed the Devicemaster port setting from "connect always" to "connect on data" and the problem disappeared. I have great respect for Hans Passant but I do not agree that this is an error code that you can easily solve by scrutinizing code.
In my case the issue was caused by the fact that starting from .NET 5 or 6 you must either call async methods for async stream, or sync methods for sync strem.
So that if I called FlushAsync I must have get context using GetContextAsync
What I do when it happens is Disable the COM port into the Device Manager and Enable it again.
It stop the communications with another program or thread and become free for you.
I hope this works for you. Regards.
I ran into this error while using Entity Framework Core with Azure Sql Server running in Debug mode in Visual Studio. I figured out that it is an exception, but not a problem. EF is written to handle this exception gracefully and complete the work. I had VS set to break on all exceptions, so it did. Once I unchecked the check box in VS to not break on this exception, my C# code, calling EF, using Azure Sql worked every time.
There are several questions on StackOverflow regarding closing WCF connections, however the highest ranking answers refers to this blog:
http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html
I have a problem with this technique when I set a breakpoint at the server and let the client hang for more than one minute. (I'm intentionally creating a timeout exception)
The issue is that the client appears to "hang" until the server is done processing. My guess is that everything is being cleaned up post-exception.
In regard to the TimeOutException it appears that the retry() logic of the client will continue to resubmit the query to the server over and over again, where I can see the server-side debugger queue up the requests and then execute each queued request concurrently. My code wan't expecting WCF to act this way and may be the cause of data corruption issues I'm seeing.
Something doesn't totally add up with this solution.
What is the all-encompassing modern way
of dealing with faults and exceptions
in a WCF proxy?
Update
Admittedly, this is a bit of mundane code to write. I currently prefer this linked answer, and don't see any "hacks" in that code that may cause issues down the road.
This is Microsoft's recommended way to handle WCF client calls:
For more detail see: Expected Exceptions
try
{
...
double result = client.Add(value1, value2);
...
client.Close();
}
catch (TimeoutException exception)
{
Console.WriteLine("Got {0}", exception.GetType());
client.Abort();
}
catch (CommunicationException exception)
{
Console.WriteLine("Got {0}", exception.GetType());
client.Abort();
}
Additional information
So many people seem to be asking this question on WCF that Microsoft even created a dedicated sample to demonstrate how to handle exceptions:
c:\WF_WCF_Samples\WCF\Basic\Client\ExpectedExceptions\CS\client
Download the sample:
C# or VB
Considering that there are so many issues involving the using statement, (heated?) Internal discussions and threads on this issue, I'm not going to waste my time trying to become a code cowboy and find a cleaner way. I'll just suck it up, and implement WCF clients this verbose (yet trusted) way for my server applications.
Optional Additional Failures to catch
Many exceptions derive from CommunicationException and I don't think most of those exceptions should be retried. I drudged through each exception on MSDN and found a short list of retry-able exceptions (in addition to TimeOutException above). Do let me know if I missed an exception that should be retried.
Exception mostRecentEx = null;
for(int i=0; i<5; i++) // Attempt a maximum of 5 times
{
try
{
...
double result = client.Add(value1, value2);
...
client.Close();
}
// The following is typically thrown on the client when a channel is terminated due to the server closing the connection.
catch (ChannelTerminatedException cte)
{
mostRecentEx = cte;
secureSecretService.Abort();
// delay (backoff) and retry
Thread.Sleep(1000 * (i + 1));
}
// The following is thrown when a remote endpoint could not be found or reached. The endpoint may not be found or
// reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable.
catch (EndpointNotFoundException enfe)
{
mostRecentEx = enfe;
secureSecretService.Abort();
// delay (backoff) and retry
Thread.Sleep(1000 * (i + 1));
}
// The following exception that is thrown when a server is too busy to accept a message.
catch (ServerTooBusyException stbe)
{
mostRecentEx = stbe;
secureSecretService.Abort();
// delay (backoff) and retry
Thread.Sleep(1000 * (i + 1));
}
catch(Exception ex)
{
throw ex; // rethrow any other exception not defined here
}
}
if (mostRecentEx != null)
{
throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
}
Closing and Disposing a WCF Service
As that post alludes to, you Close when there were no exceptions and you Abort when there are errors. Dispose and thus Using shouldn't be used with WCF.
In an application I'm developing, I have the need to handle a socket-timeout differently from a general socket exception. The problem is that many different issues result in a SocketException and I need to know what the cause was.
There is no inner exception reported, so the only information I have to work with is the message:
"A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond"
This question has a general and specific part:
is it acceptable to write conditional logic based upon the textual representation of an exception?
Is there a way to avoid needing exception handling?
Example code below...
try
{
IPEndPoint endPoint = null;
client.Client.ReceiveTimeout = 1000;
bytes = client.Receive(ref endPoint);
}
catch( SocketException se )
{
if ( se.Message.Contains("did not properly respond after a period of time") )
{
// Handle timeout differently..
}
}
I'm wanting to cease the "wait for new data" every now and again, so that my worker thread can look to see whether it has been asked to gracefully close - I would rather avoid cross-thread termination of the socket to provide this mechanism.
of course it is! there are more descriptive fields in SocketException, you should not perform string comparison. http://msdn.microsoft.com/library/system.net.sockets.socketexception_members.aspx, especially:
ErrorCode
NativeErrorCode
SocketErrorCode
Exceptions are Culture relevant, I have "German" exception messages.
Use the SocketErrorCode.
I have the following code in a class of mine. The purpose of this class is to get the balance from a web server. Just in case something goes wrong with getting the balance. I will handle a exception. However, all this is easy to do. But I am left wondering what do I return in my catch statement.
Most of the examples I looked at just write to the console using:
Console.WriteLine(ex.Message);
That is all very well. But in a real application what do most developers do?
//Download only when the webclient is not busy.
if (!wc.IsBusy)
{
// Sleep for 1/2 second to give the server time to update the balance.
System.Threading.Thread.Sleep(500);
try
{
// Download the current balance.
wc.DownloadStringAsync(new Uri(strURL));
}
catch (WebException ex)
{
Console.Write("GetBalance(): " + ex.Message);
}
}
else
{
Console.Write("Busy please try again");
}
My function at the moment returns void. And I am just wondering what else I would return if the webclient is busy?
Many thanks for any advice,
Do not catch an exception if you cannot handle it. If you return just some value, the calling method has to check if the value is a real result or just an indicator of an exception. And now this method must decide what to do and return. And the method calling this method. And the method...
So just let the exception bubble up the stack and catch it somewhere where you can handle it. Maybe directly below the user interface and then display a message box asking if the user wants to retry or display information how to solve the problem. If you have no user interface, catch it somewhere where you can solve the problem and retry. If it is a temporary problem, retry the whole task at a reasonable level until the call succeeds.
If you want to log something, use the following pattern to log the exception an rethrow it.
try
{
DoStuff();
}
catch (Exception exception)
{
Log(exception.ToString());
throw;
}
Note that it is throw; and not throw exception;. If you do the later, you lose the original stack trace. If you can infer more details about the cause of the exception, you should wrap the caught exception into a more meaningful exception with additional information.
try
{
DoStuff();
}
catch (SpecificMeaninglessException exception)
{
Log(exception.ToString());
throw new MeaningfulException("Details about the error.", exception);
}
catch (Exception exception)
{
Log(exception.ToString());
throw;
}
You should use ex.ToString() method
Exception.Message
contains a simple description of the exception (e.g. "Object reference not set...").
Exception.ToString()
contains a description of the exception along with a complete stack trace.
Exception Handling Best Practices in .NET
You could re-run the method if the client is busy but wait a certain time before retries? Potentially with a failure after x retries.
If instead you wish to move on and simply log the problem, your catch statement could log the exception to a file-based log, event viewer, submit to a database, raise an alert (email, sms etc.) if it is necessary.
Depends on the severity of the exception.
I would suggest looking into The Exception Block from Patterns & Practices
If you're only interested in viewing the exception you should re throw the exception so who-ever is planning on handling it will still get it.
You certainly don't want to mask an unhandled exception. Let that bubble up through the stack. But if you are asking what to return if the web client is just busy, how about
returning either a random interval or some meaningful interval that the function caller should wait before attempting to download the balance again? A random number could distribute load or otherwise mitigate a collision problem. A more meaningful interval could be sent back based on the the current state of the server.
In my application, I currently stop listening when AcceptTcpClient (or EndAcceptTcpClient) throws an exception. Typically exceptions are thrown when I stop the listener (socket error 10004) or when I disconnect the network adapter.
try
{
while (true)
{
TcpClient client = listener.AcceptTcpClient();
// omitted: start new thread which handles the client connection
}
}
catch (...)
{
// omitted: handle exception, log, stop listening
}
But, are there any exceptions that are caused by the client, and would require to ignore (or log) the exception and continue calling AcceptTcpClient?
MSDN has documentation that will list all exceptions that can be thrown by methods/members/etc.
I find it easy to get where you want to go by searching google for something like "MSDN Ssystem.Net.Sockets.TcpListener class" and then navigating to the page I need.
TcpLisenter.AcceptTcpClient Method
MSDN lists 2 exceptions that can be thrown.
InvalidOperationException : The listener has not been started with a call to Start.
SocketException : Use the SocketException.ErrorCode property to obtain the specific error code. When you have obtained this code, you can refer to the Windows Sockets version 2 API error code documentation in MSDN for a detailed description of the error.