.NET 远程处理异常

发布于 2024-07-04 03:02:11 字数 545 浏览 4 评论 0原文

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

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

更新:

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

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

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

This is about when a .NET remoting exception is thrown. If you take a look at MSDN, it will mention that a remoting exception is thrown when something goes wrong with remoting. If my server is not running, I get a socket exception which is fine.

What I am trying to figure out is: does getting a remoting exception indicate for sure that my server is up and running? If yes, that would solve the problem. If not: Is there a way to figure out if the remoting exception originated on the client side or the server side?

Update:

The problem I am trying to solve is that the server is down initially and then client sends some message to the server. Now I get a socket exception saying "No connection could be made..." which is fine.

There is a thread that is sending messages to the server at regular intervals to see if the server is available. Now, the server comes up, and at that point, you could get the response which is fine or you could get some exception and most probably it will be a remote exception. So, what I am trying to ask is that: in case I don't get a message and I get a remote exception is there a chance that the server is up and running and I am still getting this exception?

All I am doing is just calling a method on the remote object that does nothing and returns. If there is no exception then I am good. Now, if there is a remoting exception and if I knew the remoting exception occurred on the server then I know in spite getting the exception, I am connected to the server.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

信仰 2024-07-11 03:02:11

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

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

If you are intending to use custom exception types to be thrown across the remoting boundray, be sure to mark these types as "[Serializable]". I can't remember the exact error message, but it perplexed me for the better part of a day the first time I saw it.

Also, just a tip, TargetInvocationException often has the REAL exception embedded in its InnerException property. There is nothing more useless than "An exception was thrown by the target of an invocation."

埋情葬爱 2024-07-11 03:02:11

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

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

Getting a remoting exception does not guarantee that your server is up and running. If something else happens to be running and listening on that port, the connection will succeed, and you will not get a socket exception. What happens in this case depends on how the application which actually got your connection behaves, but it will probably wind up generating a remoting exception in your client.

It would take a bit more investigation to verify this, but I believe the remoting exception indicates a problem in the communications between the client and the server, so there isn't a "client side" or "server side" that generated it. It means that the two weren't talking happily and it could have been caused by either one.

暮年 2024-07-11 03:02:11

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

Try assuring that you send the correct message and the messages received by the server are also correct, e.g. using assertions (it is called Design by Contract).
If you have such possibility, try debugging the server side and client side at the same time. (running two VS instances at the same time)

还在原地等你 2024-07-11 03:02:11

好吧,既然你已经这么说了,我假设你使用 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

Ok now that you have put it that way, I assume you are use TCP for remoting, for if it was via HTTP, it would be a WebException thrown when failing to connect to the (TCP network port) server. When the server has not launched the application program to register the channel on that designated TCP port, you will get a SocketException. After all, the server is not listening/responding to that port, how can the client ever make a socket connection?

But, if you get a RemotingException it need not necessarily mean the server has its proper Remoting application running fine. You could test by connecting to a wrong URI on a wrong port, like port 80 (IIS).

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

That would result in a RemotingException because while the client can make a TCP connection to port 80, it is IIS responding to the call and not the Remoting app; IIS cannot handle remoting calls directly. Having said that, a RemotingException can also jolly mean a problem at the client side. This blog article may help you understand better.

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

沒落の蓅哖 2024-07-11 03:02:11

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

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

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

If the server side application logic threw an exception, it should be able to marshal over to the client to let it know what happened. You can test this by deliberately throwing an exception in one of the remote object's methods. Then call that particular method from the client side expecting an exception:

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("=====");
}

You can expect an exception received like this

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

It should tell you the Source is at the server, with a server-side stack trace.

牵你的手,一向走下去 2024-07-11 03:02:11

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

I haven't got access to the source code of my last remoting application, but as far as I can remember we couldn't figure out a way of knowing for definite if the server was up from any of the exceptions we got.
We did check to see if the network was present and warned the user if not (a method on the Environment class I think).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文