这是关于抛出.NET远程处理异常的时候。如果你看看MSDN,它会提到当远程处理出现问题时会抛出远程异常。如果我的服务器没有运行,我会收到套接字异常,这很好。
我想弄清楚的是:获取远程异常是否表明我的服务器已启动并正在运行?如果是,那将解决问题。如果没有:有没有办法弄清楚远程异常是否源自客户端或服务器端?
我想解决的问题是服务器最初关闭,然后客户端向服务器发送一些消息。现在我得到一个套接字异常,说“不能建立连接......”这很好。
有一个线程定期向服务器发送消息,以查看服务器是否可用。现在,服务器出现了,在那时,你可以得到很好的响应,或者你可以得到一些异常,很可能它将是一个远程异常。所以,我想要问的是:如果我没有收到消息并且我得到一个远程异常,那么服务器是否有可能启动并运行,我仍然得到这个异常?
我所做的只是在远程对象上调用一个什么都不做的方法并返回。如果没有例外那么我很好。现在,如果有一个远程异常,并且如果我知道服务器上发生了远程异常,那么我知道尽管得到了异常,但我已连接到服务器。
答案 0 :(得分:2)
如果您打算使用自定义异常类型抛出远程处理的boundray,请务必将这些类型标记为“[Serializable]”。我不记得确切的错误信息,但是当我第一次见到它时,它让我感到困惑。
另外,只是一个提示,TargetInvocationException通常在其InnerException属性中嵌入了REAL异常。没有什么比“调用目标引发异常更无用了。”
答案 1 :(得分:1)
获取远程处理异常并不能保证您的服务器已启动并正在运行。如果碰巧正在运行并侦听该端口,则连接将成功,并且您将不会收到套接字异常。在这种情况下会发生什么取决于实际获得连接的应用程序的行为方式,但最终可能会在您的客户端中生成远程处理异常。
验证这一点需要更多的调查,但我相信远程处理异常表明客户端和服务器之间的通信存在问题,因此没有生成“客户端”或“服务器端”它。这意味着两人不愉快地交谈,而且可能是由任何一方引起的。
答案 2 :(得分:0)
尝试确保您发送正确的消息,并且服务器收到的消息也是正确的,例如使用断言(称为契约式设计)。 如果您有这种可能性,请尝试同时调试服务器端和客户端。 (同时运行两个VS实例)
答案 3 :(得分:0)
我无法访问我上一次远程处理应用程序的源代码,但据我记忆,我们无法找到一种方法可以确定服务器是否出现了我们获得的任何异常情况。
我们确实检查了网络是否存在,如果不存在则警告用户(我认为环境类的方法)。
答案 4 :(得分:0)
如果服务器端应用程序逻辑抛出异常,它应该能够编组到客户端以让它知道发生了什么。您可以通过故意在远程对象的某个方法中抛出异常来测试它。然后从客户端调用该特定方法,期待异常:
HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);
IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
typeof(IMyRemoteObject),
"http://localhost:1234/MyRemoteObject.soap");
Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
int tmp = obj.GetValue();
Console.WriteLine("Client.Main(): Original server side value: {0}",tmp);
Console.WriteLine("Client.Main(): Will set value to 42");
try
{
// This method will throw an ApplicationException in the server-side code.
obj.SetValue(42);
}
catch (Exception ex)
{
Console.WriteLine("=====");
Console.WriteLine("Exception type: " + ex.GetType().ToString());
Console.WriteLine("Message: " + ex.Message);
Console.WriteLine("Source: " + ex.Source);
Console.WriteLine("Stack trace: " + ex.StackTrace);
Console.WriteLine("=====");
}
你可以期待收到这样的例外
=====
Exception type: System.ApplicationException
Message: testing
Source: Server
Stack trace:
Server stack trace:
at Server.MyRemoteObject.SetValue(Int32 newval) in i:\projects\remoting.net\ch03\01_singlecallobjects\server\server.cs:line 27
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at General.IMyRemoteObject.SetValue(Int32 newval)
at Client.Client.Main(String[] args) in i:\projects\remoting.net\ch03\01_singlecallobjects\client\client.cs:line 29
=====
它应该告诉你Source在服务器上,带有服务器端堆栈跟踪。
答案 5 :(得分:0)
好了,现在你已经这样说了,我假设你使用TCP进行远程处理,因为如果是通过HTTP,那么当连接到(TCP网络端口)服务器失败时,就会抛出WebException。当服务器尚未启动应用程序以在指定的TCP端口上注册通道时,您将收到SocketException。毕竟,服务器没有监听/响应该端口,客户端如何进行套接字连接?
但是,如果你得到一个RemotingException它需要不必然意味着服务器有正确的Remoting应用程序正常运行。您可以通过在错误的端口上连接错误的URI进行测试,例如端口80(IIS)。
IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
typeof(IMyRemoteObject),
"tcp://localhost:80/MyRemoteObject.rem");
这会导致RemotingException,因为虽然客户端可以与端口80建立TCP连接,但IIS是响应呼叫而不是Remoting应用程序; IIS无法直接处理远程调用。话虽如此,RemotingException也可以在客户端快速地表示问题。这篇博客文章可以帮助您更好地理解。