这是关于何时引发 .NET 远程处理异常的情况。如果你看一下 MSDN,它会提到当远程处理出现问题时会抛出远程处理异常。如果我的服务器没有运行,我会得到一个套接字异常,这很好。

我想弄清楚的是:收到远程处理异常是否表明我的服务器已启动并正在运行?如果是的话,问题就解决了。如果不:有没有办法确定远程处理异常是源自客户端还是服务器端?

更新:

我试图解决的问题是服务器最初关闭,然后客户端向服务器发送一些消息。现在我收到一个套接字异常,提示“无法建立连接...”,这很好。

有一个线程定期向服务器发送消息以查看服务器是否可用。现在,服务器启动了,此时,您可以获得很好的响应,或者您可以获得一些异常,并且很可能是远程异常。所以,我想问的是:如果我没有收到消息并且收到远程异常,是否有可能服务器已启动并正在运行,但我仍然收到此异常?

我所做的只是在远程对象上调用一个不执行任何操作并返回的方法。如果没有例外的话我就很好。现在,如果存在远程处理异常,并且如果我知道服务器上发生了远程处理异常,那么我知道尽管出现异常,但我仍连接到服务器。

有帮助吗?

解决方案

获取远程处理异常并不能保证您的服务器正常运行。如果有其他东西正在该端口上运行和侦听,则连接将成功,并且您不会收到套接字异常。在这种情况下会发生什么取决于实际获得连接的应用程序的行为方式,但它可能最终会在客户端中生成远程处理异常。

需要更多的调查来验证这一点,但我相信远程处理异常表明客户端和服务器之间的通信存在问题,因此不存在生成它的“客户端”或“服务器端”。这说明两人谈得并不愉快,也可能是其中一方造成的。

其他提示

如果您打算使用跨远程处理边界抛出的自定义异常类型,请务必将这些类型标记为“[Serializable]”。我不记得确切的错误消息,但当我第一次看到它时,它让我困惑了一天。

另外,只是提示一下,TargetInitationException 通常在其 InnerException 属性中嵌入了 REAL 异常。没有什么比“调用目标引发异常”更无用的了。

尝试确保您发送正确的消息并且服务器接收到的消息也正确,例如使用断言(称为契约设计)。如果有这种可能性,请尝试同时调试服务器端和客户端。(同时运行两个VS实例)

我无法访问上一个远程处理应用程序的源代码,但据我记得,我们无法找到一种方法来确定服务器是否已从我们收到的任何异常中恢复过来。
我们确实检查网络是否存在,如果不存在则警告用户(我认为是环境类的方法)。

如果服务器端应用程序逻辑抛出异常,它应该能够编组到客户端以使其知道发生了什么。您可以通过故意在远程对象的方法之一中引发异常来测试这一点。然后从客户端调用该特定方法,期望出现异常:

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
=====

它应该告诉您源位于服务器上,并带有服务器端堆栈跟踪。

好吧,既然你已经这么说了,我假设你使用 TCP 进行远程处理,因为如果是通过 HTTP,那么在无法连接到(TCP 网络端口)服务器时将会抛出 WebException。当服务器尚未启动应用程序在指定的 TCP 端口上注册通道时,您将收到 SocketException。毕竟,服务器没有侦听/响应该端口,客户端如何建立套接字连接?

但是,如果您收到 RemotingException,则需要 不是 必然意味着服务器有其正确的远程处理应用程序运行良好。您可以通过连接到错误端口上的错误 URI 进行测试,例如端口 80 (IIS)。

IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
    typeof(IMyRemoteObject),
    "tcp://localhost:80/MyRemoteObject.rem");

这将导致 RemotingException,因为虽然客户端可以与端口 80 建立 TCP 连接,但响应该调用的是 IIS,而不是 Remoting 应用程序;IIS 无法直接处理远程调用。话虽如此,RemotingException 也可能意味着客户端出现问题。这篇博客文章可能会帮助您更好地理解。

http://www.cookcomputing.com/blog/archives/000308.html

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top