6

i have a really weird sitation going on in my code. I'm developping a c# chat client-server application. When i close the server i want the client to be automatically closed. The client is reading from the TcpClient object using a StremReader. The client is in a while loop where it reads a line(StreamReader.ReadLine()) and then doing some operations with the line it reads. When the serever gets closed, i also close the tcp connection server-side. So, i'm expecting the client to see a SocketException caused by the readline, catch it and exit. But the exception doesn't get caught! Here's the client loop code:

 while (true)
 {
     try
     {
          ricev = read.ReadLine();
     }
     catch(SocketException exc)
     {
         //It never gets in here
     }
     chat.Invoke(showMessage, ricev);
 }

When i close the server, visual studio tells me that a "System.Net.Sockets.SocketException" first-chance exception was raised in System.dll, but i cannot catch it. Why does that happen? i also tried to catch any generic exception with a

catch
{
}

block, but that doesn't work either.

Any help will be appreciated!

EDIT: after trying some more times, i actually found out that SocketException doesn't get raised at all. That's so weird, as i said in a comment, in the opposite situation, when the client gets closed before the server, the exception gets raised and i can canth it. I don't really know what's going on....

l.moretto
  • 193
  • 1
  • 13
  • 1
    Are you running this in the debugger? A first chance exception is when an exception gets thrown but may be caught. Second-chance exceptions are when it does not get caught and terminates the program. Are you running under VS? Or running it stand-alone? – James Michael Hare Jul 12 '11 at 14:19
  • Ought to work. Debug + Exceptions, tick the Thrown box for CLR exceptions. Wait for the debugger to break and start single-stepping to see why it doesn't work. – Hans Passant Jul 12 '11 at 14:23
  • Try adding a catch(Exception e) clause and see if it gets caught there – Evan M Jul 12 '11 at 14:24
  • Im' running this inside VS in debug mode. I already tried using catch(Exception e) but that doesn't work either. – l.moretto Jul 12 '11 at 14:29
  • Did it break in the constructor for the `StreamReader`? – user7116 Jul 12 '11 at 16:30

6 Answers6

1

If I understand you well the scenario is when you call Stop method at TcpListener object "_server.Stop()", it will not throw SocketException at the client side when call Read on the stream... I don't know why this is happening but I have a work ground around it. it is by accessing to the underlying Socket on the TcpListener and call Shutdown on it:

_server.Stop();
_server.Server.Shutdown(SocketShutdown.Both);//now at your "read.ReadLine();" will throw SocketException

Edit: You stated at comment:

actually i'm closing the tcpclient returned by the listener on the accept method. connClient.Close()

If are stopping the tcpListerner "_server.Stop()" and then close the clients getted from _server.AcceptTcpCleint() method, then at the at reader.ReadLine() will throw IOException: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall I tested it myself.

Jalal Said
  • 15,906
  • 7
  • 45
  • 68
  • no, actually i'm closing the tcpclient returned by the listener on the accept method. connClient.Close(). Is this the right way to close a connection? From the documentation in visual studio, it says that the close method frees any resource of the TcpClient and asks for the underlying conneciton to be closed. Am i wrong? anyway, i will surely try to shutdown the socket and see if that works, thanks for the advice – l.moretto Jul 13 '11 at 07:17
  • @l.moretto: If you `closing the tcpclient returned by the listener on the accept method. connClient.Close()` then it will throw `IOException` at the `reader.ReadLine()`.. check my answer edit. – Jalal Said Jul 13 '11 at 11:25
  • Ok, thanks for the help. I will try to do this. Anyway, i almost solved this by also checking if the readline returns a null string in the reading loop. if that happensa i break the loop. I also added a "finally" block which gets executed if i get an exception or the loop ends, so in any case i am now able to end the client program when the conneciton i closed by the server. – l.moretto Jul 13 '11 at 16:12
  • The `ReadLine()` method is block method that means it will block before you get your null or the string; _waiting_ for some data "a line" to be added so it can read it... i.e: you will not get the null or any data it just will block there as usual without throwing exceptions. – Jalal Said Jul 13 '11 at 17:08
  • yes, but as soon as the connection gets closed it returns null, i tested that – l.moretto Jul 13 '11 at 18:53
0

visual studio tells me that a "System.Net.Sockets.SocketException" first-chance exception was raised in System.dll, but i cannot catch it. Why does that happen?

First chance exceptions are intercepted by the debugger and interrupts you. It is the second chance exception that gets you into your catch block and that's why you do not get into your catch block on first chance. See this article for more information.

Extracted from the article I mentioned above

Does a first chance exception mean there is a problem in my code? First chance exception messages most often do not mean there is a problem in the code. For applications / components which handle exceptions gracefully, first chance exception messages let the developer know that an exceptional situation was encountered and was handled.

On a side note, you can always configure your debugger to not stop on first chance exceptions.

GETah
  • 20,922
  • 7
  • 61
  • 103
0

When you close the server socket, the other side receives a message of zero bytes. This indicates that the server has closed down properly:

If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes.

http://msdn.microsoft.com/en-us/library/8s4y8aff.aspx

Exceptions are thrown only for exceptional situations - for instance if you reboot the server computer while your client was connected to it - not for normal program flow.

The ReadLine() operation should also not throw an exception but simply return null when this happens:

Return value

The next line from the input stream, or null if the end of the input stream is reached.

http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
0

I've this problem before and turn's out that I've been activate "Break when CLR Exception thrown and didn't uncheck it back"

So,check of you didn't uncheck this feature by
Press Alt+Ctr + E scroll down to Common Runtime Language Exception and make sure to uncheck "Thrown" Check box. I hope this help you.

0

If you are calling Invoke, odds are that the exception will be wrapped in a TargetInvocationException.

leppie
  • 115,091
  • 17
  • 196
  • 297
-2

This is because .Net uses unsafe methods for Send/Receive methods.you have to handle your Program Coontext's UnhandledException

pingsft
  • 316
  • 3
  • 4