. net Remoting例外

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

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

更新:

我试图解决的问题是,服务器最初是关闭的,然后客户端发送一些消息到服务器。现在我得到一个套接字异常,说“没有连接可以建立…”’这很好。

有一个线程定期向服务器发送消息,以查看服务器是否可用。现在,服务器启动,这时,你可以得到响应,这很好你也可以得到一些异常,很可能是一个远程异常。我想问的是,如果我没有收到消息而我收到了一个远程异常是否有可能服务器已经启动并运行,而我仍然收到这个异常?

我所做的只是在远程对象上调用一个不做任何事情并返回的方法。如果没有例外,那我就很好。现在,如果有一个远程异常,如果我知道远程异常发生在服务器上,那么我知道尽管得到了异常,但我已经连接到服务器。

请先 登录 后评论

6 个回答

sumek

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

请先 登录 后评论
Rikalous

我还不能访问上一个远程应用程序的源代码,但据我所知,我们无法从我们得到的任何异常中确定服务器是否启动。
我们检查网络是否存在,如果不存在就警告用户(我认为这是Environment类上的一个方法)。

请先 登录 后评论
Thomee

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

要验证这一点需要进行更多的调查,但我相信remoting异常表明客户端和服务器之间的通信存在问题,因此不存在“客户端”或“服务器端”生成它。这意味着两个人聊得不开心可能是其中一人造成的。

请先 登录 后评论
icelava

如果服务器端应用程序逻辑抛出异常,它应该能够封送到客户端,让客户端知道发生了什么。您可以通过故意在远程对象的一个方法中抛出异常来对此进行测试。然后从客户端调用那个特定的方法,期待一个异常:

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位于服务器端,并提供服务器端堆栈跟踪。

请先 登录 后评论
Steve Dinn

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

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

请先 登录 后评论
icelava

好了,既然您已经这样说了,我假设您正在使用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

请先 登录 后评论
  • 17 关注
  • 0 收藏,234 浏览
  • Community 提出于 2022-11-02 18:58