5

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

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

更新:

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

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

我所做的只是在远程对象上调用一个什么都不做并返回的方法。如果没有例外,那我很好。现在,如果存在远程处理异常并且我知道服务器上发生了远程处理异常,那么我知道尽管收到了异常,但我已连接到服务器。

4

6 回答 6

2

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

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

于 2008-09-16T16:57:55.330 回答
1

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

验证这一点需要更多调查,但我相信远程处理异常表明客户端和服务器之间的通信存在问题,因此没有“客户端”或“服务器端”生成它。这意味着两人谈话不愉快,可能是由任何一方造成的。

于 2008-09-16T16:17:40.950 回答
0

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

于 2008-09-16T16:00:45.093 回答
0

我无法访问我上一个远程处理应用程序的源代码,但据我所知,我们无法找到一种方法来确定服务器是否因我们遇到的任何异常而启动。
我们确实检查了网络是否存在,如果不存在则警告用户(我认为是 Environment 类的一种方法)。

于 2008-09-16T16:13:30.213 回答
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
=====

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

于 2008-09-16T16:44:08.827 回答
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 也可能意味着客户端出现问题。这篇博客文章可以帮助您更好地理解。

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

于 2008-09-16T17:09:08.753 回答