2009-11-02 212 views
0

我正在处理客户端服务器应用程序。客户端不断从服务器读取数据,因此当服务器关闭或断开时,客户端崩溃。我尝试了一个try/catch块,但它不起作用。我的客户端应用程序是用C++编写的。我希望客户端显示一些正确的消息,如“服务器断开连接”,然后退出。客户端如何正常检测服务器何时断开连接?

+5

你有一个很好的代码片段? – sharptooth 2009-11-02 13:12:46

+1

你能给我们提供更多的细节,代码示例可能吗? – varnie 2009-11-02 13:34:34

+1

我建议你不仅添加一段代码给我们一些迹象,说明你的try/catch为什么不起作用,还有一些关于你的客户端与服务器通信的信息(socket?[D] COM?CORBA [别笑!]?网络服务?其他?)。描述当你试图捕捉异常时究竟发生了什么也是有帮助的:某种形式的try/catch应该可以解决这个问题,除非你使用了一些......异常......远程库。 – 2009-11-02 13:38:38

回答

0

看一下Code Project Len Holgates的东西 - he hangs out here too。他是插座上的大脑和他的IOCP的东西是我见过的最好的,我知道他的东西不正是你在找什么。

+3

-1。听起来像“使用Google”。 – 2009-11-02 13:28:38

+1

+1:不,不。 – 2009-11-02 13:38:40

+1

请提供更具体的链接,例如Holgates解释这个问题的答案的文章。 – 2009-11-02 19:55:56

0

推广异常处理来处理抛出的任何类型的异常;

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

处理特定类型的异常,如COM异常

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

你也可以去MSDNHERE更详细的信息。

+0

如果你的套接字读取没有抛出异常,你需要这样做才能使catch生效。看看这个更多的信息 - http://www.cplusplus.com/doc/tutorial/exceptions/。 – zooropa 2009-11-02 13:45:36

1

没有关于错误的更多细节,我们都只是猜测。

是什么让你相信异常导致错误?

如果使用堆栈安全检查进行编译,它可能是分段错误或访问冲突或堆栈粉碎。

如果套接字处理中的某些内容覆盖主处理函数的返回地址,则很容易发生这种情况。当套接字关闭时,处理函数将会崩溃。

或者它可能是由双重空闲或通过写入已释放的内存导致的堆内存损坏。

0

你还没有告诉我们很多,所以我不得不做一些猜测。

在C++中,不像Java或C#中那样使用异常,其中(几乎)所有错误处理都是使用异常完成的。在C++中,还有一些其他独立的机制也需要使用。

如果您在Java中出现空指针错误,Java将抛出一个NullPointerException,您可以使用try-catch块捕获该错误。在C++中,你会得到一个分段错误(或者不是,或者别的,这取决于你正在使用的是哪个操作系统),其中而不是被try-catch块捕获。这是完全不同的机制。

如果您尝试将文本字符串转换为数字,但不起作用,Java将引发NumberFormatException。在C++中,你必须事后检查它是否工作。 try-catch块不会帮助你。

所以,只要将你的库调用放在try-catch块中就可能没有帮助。如果你的套接字库在服务器关闭时没有抛出异常(我认为它不太可能),那么几乎可以肯定有其他一些方法来检查它。也许有读取调用的返回值,如果套接字的另一端已关闭,则该值为负值?

如果您没有检查关闭的套接字,并且您的程序不断尝试读取并处理收到的数据,就好像套接字仍然打开一样,程序很可能会崩溃。但是,这种崩溃也不能通过尝试抓取来处理。

总而言之,try-catch可能是解决问题的错误方法,您需要检查套接字库的文档以了解如何执行此操作。

1

我不确定你在哪个平台上运行,但如果它是基于Unix的平台,那么你可能会遇到一个“特性”,远程关闭的TCP连接会导致你的客户端SIGPIPE信号,当它试图写入套接字。如果SIGPIPE信号未处理(除非您明确安装了处理程序),则未处理的信号将导致程序终止。

避免这个问题的最简单方法是包含在这个程序的开头:

#include <signal.h> 

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

一旦做到这一点,已关闭的连接将更加微妙的方式传达给你,例如select()返回准备好读取,然后recv()返回0(意味着EOF)。

SIGPIPE无法在Windows下发生的,所以如果你的程序仅适用于Windows,你可以忽略这个帖子:)

相关问题