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
相关产品推荐
相关产品推荐

