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

System.Net.WebSockets.WebSocket能否获取含临时端口的本地端点?

获取ClientWebSocket的本地端点(含临时端口)

可以获取,但System.Net.WebSockets.WebSocket抽象类本身没有直接暴露本地/远程端点的公共API。不过针对你使用的ClientWebSocket,有两种可行的方案:

方案1:通过反射获取ClientWebSocket内部的底层Socket

ClientWebSocket的底层依赖一个内部的Socket实例,我们可以通过反射来访问这个实例,进而获取LocalEndPoint:

private System.Net.WebSockets.WebSocket _webSocket;
private string _uri = "ws://address";
private int ConnectTimeoutSec = 10;

using (System.Net.WebSockets.ClientWebSocket clientWebSocket = new System.Net.WebSockets.ClientWebSocket())
{                        
    _webSocket = clientWebSocket;       
    var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(ConnectTimeoutSec));

    await clientWebSocket.ConnectAsync(new Uri(_uri), cancellationTokenSource.Token);

    // 反射获取内部Socket
    var innerWebSocketField = clientWebSocket.GetType().GetField("_innerWebSocket", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    if (innerWebSocketField != null)
    {
        var innerWebSocket = innerWebSocketField.GetValue(clientWebSocket);
        var socketProperty = innerWebSocket.GetType().GetProperty("Socket", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
        if (socketProperty != null)
        {
            var socket = (System.Net.Sockets.Socket)socketProperty.GetValue(innerWebSocket);
            if (socket != null)
            {
                // 获取本地端点(含临时端口)
                var localEndPoint = socket.LocalEndPoint;
                Console.WriteLine($"本地端点:{localEndPoint}");
                // 也可以获取远程端点
                var remoteEndPoint = socket.RemoteEndPoint;
                Console.WriteLine($"远程端点:{remoteEndPoint}");
            }
        }
    }
}

注意事项

  • 这种方法依赖.NET的内部实现细节,不同版本(如.NET Framework、.NET Core、.NET 6+)的内部字段/属性名称可能发生变化,存在版本兼容性风险,升级.NET版本时需要验证代码是否可用。

方案2:手动创建Socket并包装为WebSocket(更稳定)

如果需要更稳定的实现,可以手动创建Socket对象,连接后将其包装为WebSocket,这样就能直接持有Socket实例,随时获取端点信息:

private System.Net.WebSockets.WebSocket _webSocket;
private string _serverIp = "服务器IP";
private int _serverPort = 80; // WebSocket服务器端口

// 手动创建Socket
var socket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
await socket.ConnectAsync(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(_serverIp), _serverPort));

// 将Socket包装为WebSocket
using var stream = new System.Net.Sockets.NetworkStream(socket, ownsSocket: true);
_webSocket = System.Net.WebSockets.WebSocket.CreateFromStream(
    stream, 
    isServer: false, 
    subProtocol: null, 
    keepAliveInterval: TimeSpan.FromSeconds(30)
);

// 直接获取本地端点
var localEndPoint = socket.LocalEndPoint;
Console.WriteLine($"本地端点:{localEndPoint}");

// 后续使用_webSocket进行通信
// ...

// 通信结束后释放资源
await _webSocket.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "正常关闭", CancellationToken.None);
stream.Dispose();

优势

  • 完全不依赖内部实现,兼容性更好,能直接控制Socket的生命周期和参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:10:34