views:

273

answers:

5

I am working on a client-server application. The client continuously reads data from server, so when a server is closed or disconnects then the client crashes. I tried a try/catch block, but it didn't work. My client application is written in C++. I want the client to display some proper message like "Server disconnected," then exit.

A: 

Take a look on Code Project for Len Holgates stuff - he hangs out here too. He is the brain on Sockets and his IOCP stuff is the best I've seen, and I know his stuff does exactly what you are looking for.

graham.reeds
-1. Sounds like "Use Google".
Kirill V. Lyadvinsky
+1: No it doesn't.
Mike Burton
Please provide more specific links, such as to an article where Holgates explains the answer to this question.
Rob Kennedy
He doesn't explain it in his articles. Take a look at the source here: http://www.codeproject.com/KB/IP/jbsocketserver2.aspx
graham.reeds
A: 

To generalize exception handling to handle any type of exception that is thrown;

try
{
 // try something
}
catch(...)
{
 // handle exception
}

To handle a specific type of exception, such as a com exception

try
{
 //try something
}
catch(_com_error &e)
{
 // handle exception
}

You could also go MSDN or HERE for more detailed information.

ChadNC
If your socket read doesn't throw an exception, you need to do that in order for the catch to work. Take a look at this for more info - http://www.cplusplus.com/doc/tutorial/exceptions/.
zooropa
+1  A: 

Without more details about the error, we are all just guessing.

What makes you believe an exception is causing the error?

It might be a segmentation fault or access violation or stack smashing if you compiled with stack security checking.

This can easily happen if something in the socket processing overwrites the return address of the main handling function. The handling function will then crash when the socket closes.

Or it could be heap memory corruption caused by a double free or by writing to memory that has been freed.

Zan Lynx
A: 

You haven't told us much, so I'll have to make some guesses.

In C++, exceptions are not used like in Java or C#, where (almost) all error handling is done using exceptions. In C++, there are some other, separate, mechanisms that you also need to use.

If you get a null pointer error in Java, Java throws a NullPointerException, which you can catch with a try-catch block. In C++, you get a segmentation fault (or not, or something else, depending on which OS you are using), which can not be caught by a try-catch block. It's a completely different mechanism.

If you try to translate a text string to a number, and it doesn't work, Java throws a NumberFormatException. In C++, you have to check afterwards if it worked. A try-catch block won't help you.

So, just enclosing your library calls in a try-catch block might not help you. If your socket library doesn't throw an exception when the server closes (and I think it is unlikely that it does), there is almost certainly some other way to check for it. Perhaps there is a returned value from a read call, that will be negative if the other end of the socket has been closed?

And if you don't check for closed sockets, and your program keeps trying to read and work with received data, as if the socket had still been open, it is likely that the program will crash. But this crash can't be handled by try-catch either.

So, in summary, try-catch is probably the wrong way to solve your problem, and you need to check the documentation for your socket library to see how to do it.

Thomas Padron-McCarthy
+1  A: 

I'm not sure what platform you're running on, but if it's a Unix-based platform, then you might be running into a "feature" where a remote-closed TCP connection can cause your client to raise a SIGPIPE signal when it tries to write to the socket. If the SIGPIPE signal goes unhandled (which it will unless you've explicitly installed a handler), then the unhandled signal will cause your program to terminate.

The easiest way to avoid the problem is to include this at the beginning of your program:

#include <signal.h>

// [... somewhere near the top of main(), perhaps ...]
signal(SIGPIPE, SIG_IGN);

Once that is done, the closed connection will be communicated to you in more subtle ways, e.g. select() returning ready for read and then recv() returning 0 (meaning EOF).

SIGPIPE doesn't happen under Windows, so if your program is Windows only you can ignore this post :)

Jeremy Friesner