.NET 远程处理目标拒绝单个调用 - 返回套接字异常

Posted

技术标签:

【中文标题】.NET 远程处理目标拒绝单个调用 - 返回套接字异常【英文标题】:.NET remoting target refusing a single call - returns socketexception 【发布时间】:2020-06-04 23:09:32 【问题描述】:

我有一个老式的 .NET 远程处理应用程序,我需要对其进行一些扩展。作为其中的一部分,我将它带到了 .NET 4.0。 (之前是.NET 2.0)托管的界面是这样的

    public interface IRemoteSupportVM
    
        string runAnOperation(Customer cust, List<CustomRoute> routes);

        string runAnotherOperation(string customer, string routes);

        string runAThirdOperation(List<string> pathsToBeCleaned);

        string writeFile(string path, string filename, int type, byte[] data);

        string readFile(string path, string filename, out byte[] data);

        string deleteFile(string path, string filename);

        long ping();
    

ping、readFile、writeFile 和 deleteFile 工作正常。当我调用 runAnOperation/runAnotherOperation/runAThirdOperation 时,我会立即收到一个 SocketExcepting 告诉我

连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应

现在我这是一堆废话,因为所有其他调用都工作得很好,而且,目标确实收到了调用并执行了它的事情。但是由于客户端认为调用失败了,调用 connect 之后的所有事情也都失败了。

该解决方案还有许多其他远程接口,据我所知,除了这两个方法调用之外,它们都可以工作。知道什么会绊倒 .NET 远程调用者吗?

@edit:我注意到另一件事:run* 操作需要一段时间才能完成。其他操作立即返回。由于我有remoting接口两边的代码,所以我在ping()的实现上设置了一个断点,现在客户端调用ping的时候我也得到了一个SocketException。所以这似乎是我不知道的超时。

【问题讨论】:

您不能有两个具有相同源 IP、目标 IP 和端口号的连接,因此连接被拒绝。从 cmd.exe > Netstat -a 检查连接状态并查看连接是否正在关闭。 连接保持打开状态。在调用 connect() 并获得 SocketException 之后,我可以立即在同一个代理上调用 ping() 并且它工作正常。 那么为什么要打开已经打开的连接? 就像@jdweng 说的,你只能有一个活动连接。所以你要么需要检查你是否已经有一个活动的连接,如果有的话就跳过建立一个新的连接,或者你应该在使用它后立即处理它并使东西线程安全。 啊,现在我知道你在说什么了。名称连接具有误导性。它没有打开(网络/远程处理/tcp)连接..它告诉远程端做某事。想象一下,为了清楚起见,该方法被称为“runSomeAction”。我将调整问题以更好地反映这一点 【参考方案1】:

好的,经过痛苦的试错期,我终于找到了罪魁祸首。这是通道初始化时的超时。这就是它在远程端代码中的样子:

            IDictionary props = new Hashtable
            
                ["port"] = config.Port,
                ["timeout"] = config.RemotingTimeout,
            ;
            var channel = new TcpChannel(props, clientProv, serverProv);

现在看来 timeout 属性对 .NET 2.0 没有影响 - 有很多谷歌搜索结果表明该效果。但是,在 .NET 4.0 中似乎突然需要。每个远程调用都被包装 IAsync* Begin/EnvInvoke 以确保在所需的超时之后得到结果(即使该结果是服务器没有及时提供结果)。因此,要么没有人注意到超时没有任何意义,要么就是因为这个原因而放置了执行包装器(该软件是 15 年前启动的......所以谁知道呢)。

由于 config.RemotingTimeout 为 70,因此调用需要 70 毫秒才能完成,否则我会收到 SocketException。当我将 70 秒(我期待的)转换为毫秒(所以 timeout = 70000)时,事情突然开始按我预期的方式工作。

【讨论】:

以上是关于.NET 远程处理目标拒绝单个调用 - 返回套接字异常的主要内容,如果未能解决你的问题,请参考以下文章

因为目标机器主动拒绝而无法建立连接?

是否是侦听服务结构远程端点的单个线程

处理异步套接字(.Net)后仍然会调用回调

C# 客户端 Python 服务器:连接被拒绝

关于.net 调用java的webservice时,返回的对象是null,该怎么处理

线程“主”java.net.ConnectException 中的异常:连接被拒绝:套接字编程 Java 中的线程