C# Try-catch does not catch the exception - c#

I have a confusing problem and I could not any way to workaround it. I have a couple of lines of codes, and at some point, the Send function throws a System.Net.Sockets.SocketException. However, even though try has the catch block, it does not catches the exception and continue with normal flow. When I try to run the case where it needs to throw same exception, catch captures it pretty well.
Things I have tried:
Trying to change VS debugging settings 'Enable Only For My Code', but
it is already disabled.
I tried to both Debug and Release modes.
I tried using general Exception catcher, but none of them worked.
Here is the code, at some point, the connection from the server closes and the c Socket disconnects. It returns the System.Net.Sockets.SocketException, but below catch does not capture it.
try
{
// Some code here . . .
c.Send(clientData);
Print("Started uploading the file " + uploadFilename + ".");
upBox.Text = "";
Print("Finished uploading the file " + uploadFilename + ".");
}
catch (System.Net.Sockets.SocketException)
{
Print("You are disconnected from server!");
}

The reason you're not getting an exception ...
... is that no exception has occurred!
TCP/IP itself won't necessarily "notice" a disconnect ... unless you explicitly try to write to a closed socket.
Definitely check out Beej's Guide to Network Programming:
http://www.beej.us/guide/bgnet/.
See also:
http://stefan.buettcher.org/cs/conn_closed.html,
How to detect a TCP socket disconnection (with C Berkeley socket)

Related

How do I tell apart a read error from a write error in a socket?

I am creating a server for a game that deals with lots of TCP connections, and I need to deal with a sudden loss of connection (pc crash, game process killed, internet connection lost, ectect). The problem I currently have is that I can't tell apart a read error from a write error since both throw an IOException. even the underlying exception is the same (SocketException), the only difference being that one occurs on Socket.Send() and the other on Socket.Receive() respectively. I could of course compare the exception message, but that would become a problem as soon as the system language changes (and lets be honest, that would be a pretty messy approach anyway).
I tried comparing the Hresult but since the underlying exception is the same, so is the Hresult. I also tried getHashCode() but this one changes from player to player.
Any other ways I could tell apart those 2 situations?
To clarify, we're talking about the exception that comes up when using TcpClient.read() or TcpClient.write() on a TcpClient whose connection has been unexpectedly closed.
You could try wrapping the send and receive functions in a try-catch block, and use the Data property to tell exceptions from read and write apart:
enum ReadOrWrite { Read, Write }
void Foo()
{
try
{
socket.Receive();
}
catch (IOException ex)
{
ex.Data.Add("readOrWrite", ReadOrWrite.Read);
throw;
}
}
And this is where you later catch it:
try
{
Foo();
}
catch (IOException ex) when (ex.Data.Contains("readOrWrite"))
{
var readOrWrite = ex.Data["readOrWrite"];
}

Try Catch exception in a locked block of code

I have an issue when there is an exception in a block of code that uses a lock. I am reading and writing to a serial port and there are several different threads that need access to the same serial port. This is managed by a lock. I have no issues except if the serial port stops working. This can happen since the software controls an RF transmitter and occasionally the rf can cause usb to serial ports to stop functioning. If you then attempt to write to the port you will get a write timeout. I tried handling this from a try - catch exception handler. However, the program locks hard at that point and has to have the task killed. I am not sure if this is coming from the exception or the message box I am trying to display since it could result from a background thread. Here is the code:
lock (_object)
{
try
{
if (portOpened)
{
port.Write(data);
}
else
{
MessageBox.Show("The radio is not connected. Please select a ComPort in the settings dialog");
}
}
catch (Exception x) //this will capture a write exception.
{
MessageBox.Show("The program is unable to write to the serial port. Select OK to close the program";
Application.Exit();
}
finally
{
}
}
Thanks for any help
If you want to force to exit the app, Application.Exit is not a good candidate, as it simply pushes the Close request on message queues of all threads, but does not force anything. If you want to stop app at any cost, use Environment.Exit(exitCode), or may be even better Environment.FailFast, with specified exception so it will be logged into the system's log: convenient for future investigations.

Accepted way to prevent "The remote host closed the connection" exception

I'm constantly getting the following exception which is caused by a user initiating a download and it consequently failing (or being cancelled):
Error Message : The remote host closed
the connection. The error code is
0x80072746. Stack Trace : at
System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.FlushCore(Byte[]
status, Byte[] header, Int32
keepConnected, Int32 totalBodySize,
Int32 numBodyFragments, IntPtr[]
bodyFragments, Int32[]
bodyFragmentLengths, Int32
doneWithSession, Int32 finalStatus,
Boolean& async) at
System.Web.Hosting.ISAPIWorkerRequest.FlushCachedResponse(Boolean
isFinal) at
System.Web.Hosting.ISAPIWorkerRequest.FlushResponse(Boolean
finalFlush) at
I've searched all over the internet, and found an interesting article, however there doesn't seem to be a definitive answer as the best way to prevent this filling up the logs.
The user sees no error and there's no actual problem in the app as it occurs only (to my understanding) in situations out of its control (user cancelling download or loss of connection) but there has to be a way to prevent such an exception being reported.
I hate to say it but I'm tempted to check for this exception and empty catch block its ass away - but this makes me feel like a dirty programmer.
So - what is the accepted method of preventing this exception filling up my mailbox?
The error occurs when you try to send a response to the client but they have disconnected. You can verify this by setting a breakpoint on the Response.Redirect or wherever you are sending data to the client, wait for Visual Studio to hit the breakpoint, then cancel the request in IE (using the x in the location bar). This should cause the error to occur.
To capture the error you can use the following:
try
{
Response.Redirect("~/SomePage.aspx");
Response.End();
}
catch (System.Threading.ThreadAbortException)
{
// Do nothing. This will happen normally after the redirect.
}
catch (System.Web.HttpException ex)
{
if (ex.ErrorCode == unchecked((int)0x80070057)) //Error Code = -2147024809
{
// Do nothing. This will happen if browser closes connection.
}
else
{
throw ex;
}
}
Or in C# 6 you can use Exception filters to prevent having to re throw the error:
try
{
Response.Redirect("~/SomePage.aspx");
Response.End();
}
catch (System.Threading.ThreadAbortException)
{
// Do nothing. This will happen normally after the redirect.
}
catch (System.Web.HttpException ex) when (ex.ErrorCode == unchecked((int)0x80070057))
{
// Do nothing. This will happen if browser closes connection.
}
Which is a better debugging experience since it will stop on the statement throwing the exception with the current state and all local variables preserved instead of on the throw inside the catch block.
You cannot prevent a remote Host to close anything.
And in some protocols this is the normal (or at least accepted) way to say goodbye.
So you will have to handle this specific exception.
From a practical perspective, there is nothing wrong with cancelling a download by virtue of a dead computer or a killed web session, therefore catching remote host closed exceptions is perfectly acceptable.

Handle Socket.ReceiveFrom with timeout without spamming console

I am writing a ServerLocator that basically broadcast a port to find a server which will respond with an IPEndPoint and I need the search to be able to timeout if nothing is found on the current IPHost and then move on with the next one.
Right now I am doing something like this (I have removed some parts of this code so it only includes what is needed to display my problem. There is also some client bindings going on here)
string serverIp = string.Empty;
while(string.isNullOrEmpty(serverIp))
{
foreach (IPAddress adress in ipHosts.AddressList)
{
using(Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
{
try
{
client.ReceiveFrom(buffer, ref tempRemoteEP);
//Get server IP
serverIp = tempRemoteEP.ToString().Split(":".ToCharArray(), 2)[0];
break;
}
catch(SocketException e)
{
// We expect connection attempt to time out if we cant find any server on this port and nic. Just continue with the next
if (e.SocketErrorCode == SocketError.TimedOut)
{
continue;
}
}
}
}
}
This works as expected except that the console gets spammed with:
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
Is there a good way to handle exceptions like this without spamming the console? Or could I handle this in some other way to be able to avoid the need of exception from timeout?
Thanks.
There's really no need to worry about this if the program keeps running, there's a lot of these exceptions being sent in a program. See this article for more on "First time exceptions".
Also check this link to see how you can configure Visual Studio on how to handle the exceptions. If you configure these you can break (instead of continue) on the exceptions and see what's really going on. However, do note that hiding the exceptions does not seem to work in debug, see here or here But as #Cipi pointed out, it should not be visible in Release.

How to check if a server is listening without exception handling

I'm working on two apps that connect to eachother using TCP. At one point, one of them is trying to connect using a TcpClient, but the other app is not guaranteed to have started listening yet (using TcpListener).
My first attempt was this:
TcpClient c = null;
while (true)
{
try
{
c = new TcpClient();
c.NoDelay = true;
c.Connect( ip, port );
break;
}
catch (SocketException ex)
{
Console.WriteLine(string.Format("Could not connect to {0}:{1}, retrying...", ip, port));
Thread.Sleep( 500 );
}
}
However, the problem with this is that it relies on exception handling which is a bit of a nuisance for me, because I have VS set up to catch any thrown exceptions ("Debug -> Exceptions..." menu). So every time it tries to connect, it breaks into VS and I have to press continue.
The exception I get is:
No connection could be made because the target machine actively refused it 127.0.0.1:50000
I would imagine that there would be a way to check if a server is listening on a specific port without actually trying to connect to it. I understand that just checking wouldn't be enough anyway - the server could go down between the check and the connect attempt, but it would still be much better for me while I'm developing it.
Or something like this:
TcpClient tcpClient = new TcpClient();
while ( !tcpClient.TryConnect(....) )
{ Thread.Sleep(1000); }
Analogous to this:
if (bool.TryParse( "false" ))
{ ... }
I also tried using async methods (Begin/End Connect) and setting the timeout for the ManualResetEvent manually, but that didn't work either. I've scoured the internets but I haven't been able to find a solution to this problem, which is why I'm finally posting here :)
The problem being that VS is breaking on the Exception? You you can always have VS ignore a specific family of Exceptions.
In VS, in the Debug Menu, choose "Exceptions..." and in the dialog presented you can control this.
I was going to suggest not catching an exception, so before I suggested that I test it myself, and if you set it to throw all exceptions even if you don't throw an exception its all exceptions are still being thrown. I will have to agree with Shiv Kumar, either adjust your settings while you debug your application, or accept the limitations of what you are doing.
The reason bool.TryParse works is it verifys each and every character, similarly to how Int32.TryParse makes sure that each character in the string is 0-9 or any other valid numerical symbol.
You could of course write your own networking class and not throw an exception when the connection fails.
TryParse will not throw an exception, you must catch any exception that is thrown if you use bool.Parse by try{}catch{} otherwise if you attempt to parse something that is not a boolean value it will throw an unhandled exception. TryParse was added later in the history of .NET, Parse is more of the classic method, allowing the programmer to handle all unexpected input and to validate input before trying to parse the data.
I should add that TryParse will return false if its unable to parse the value at both the method's result is false and the out variable I do believe is false.This is at least the case with Int32
http://msdn.microsoft.com/en-us/library/system.boolean.tryparse.aspx
I guess the point of pointing out how TryParse and Parse works is that they are entirely different beasts compare to TcpClient. I suppose I should clarify that the basic validation process is similar, except one throws an exception and the other one doesn't and of course one returns what was actually parsed.

Categories

Resources