You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#异步客户端Socket连接被目标机器主动拒绝问题排查

Unity C#异步TCP客户端连接本地Windows Python服务器被拒绝的原因分析

问题背景

本地Windows机器(127.0.0.1)运行Python编写的TCP服务器,监听端口10200,已通过telnet等工具确认服务正常(无防火墙拦截)。但Unity环境下的C#异步TCP客户端连接时,调用EndConnect方法抛出异常:

System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it.

客户端核心代码片段:

public void Connect (string host, int port) {  
    try { 
        IPHostEntry ipHostInfo = Dns.GetHostEntry (host);
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint remoteEP = new IPEndPoint (ipAddress, port);

        state.socket = new Socket (ipAddress.AddressFamily, 
                                   SocketType.Stream,
                                   ProtocolType.Tcp);
        state.socket.ReceiveTimeout = TcpState.RecvTimeout;

        state.socket.BeginConnect (remoteEP,
                new AsyncCallback (ConnectCallback), state);
    } catch (Exception e) {
        Debug.Log (e.ToString ());
        Disconnect ();
    }
}

// ...

private void ConnectCallback (IAsyncResult ar) {
    try { 
        TcpState state = (TcpState) ar.AsyncState;
        state.socket.EndConnect (ar);
        // 异常抛出位置
        // ...
}

注:state为封装的异步操作状态对象,Wireshark抓包显示会话不完整(flag 37),且相同代码在Linux环境下运行正常。

可能的原因

  • DNS解析返回IP地址不匹配服务器监听地址
    Windows下localhost会同时解析出IPv6(::1)和IPv4(127.0.0.1)地址,Dns.GetHostEntry返回的列表中IPv6地址可能排在首位。如果Python服务器仅监听IPv4的127.0.0.1,客户端用IPv6地址连接时会被直接拒绝。可以直接指定IPAddress.Loopback(对应IPv4回环地址),或修改Python服务器使其同时监听IPv4和IPv6。

  • Socket地址族不兼容
    若客户端通过DNS解析拿到IPv6地址,创建的Socket为AddressFamily.InterNetworkV6类型,而Python服务器仅监听IPv4端口,跨地址族的连接请求会被服务器主动拒绝(Wireshark抓到的flag 37包含RST标志,正是服务器拒绝连接的信号)。可强制客户端创建IPv4类型的Socket(指定AddressFamily.InterNetwork),或修改Python服务器开启双栈监听(使用socket.AF_INET6并设置IPV6_V6ONLY为False)。

  • Unity平台网络权限配置问题
    Windows平台的Unity应用若未正确配置网络权限,可能限制回环地址的连接。检查Player Settings中的Internet Access选项是否设置为Require或Allow;同时尝试直接传入127.0.0.1作为连接地址,绕过DNS解析环节。

  • 异步状态对象被意外篡改
    若state对象在BeginConnect到ConnectCallback的异步过程中被其他线程修改、释放或重新赋值,调用EndConnect时会触发异常。需确保state对象在异步操作完成前保持稳定,无外部线程的非法修改。

  • Windows与Linux TCP栈行为差异
    两者TCP栈对回环连接、SYN包响应的处理逻辑存在细节差异。比如Windows下对跨地址族的连接请求会直接返回RST,而Linux可能做了兼容处理,这也是代码在Linux下正常、Windows下报错的原因之一。

内容的提问来源于stack exchange,提问作者pion3k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:52:48