TCP端口检测工具实现

网络编程中,经常需要检测一个服务是否可用。通常情况下,可能会编写一个Ping程序来检查设备是否在线。但在某些情况下,不仅需要知道设备是否在线,还需要确定特定的端口是否能够响应TCP Socket连接。本文介绍如何使用C#实现一个TCP端口检测工具,该工具可以在调用其他耗时的子程序之前,检查端口是否响应连接请求。

大多数情况下,都会编写Ping程序来追踪设备是否在线,但在这个场景中,需要确保在调用其他一些耗时的子程序之前,端口能够响应TCP Socket连接。为了解决这个问题,选择了使用Sockets.TcpClient类中提供的异步BeginConnect函数,并通过线程来管理可能出现的长时间等待。然而,这种方法在代码层面上显得相当丑陋,效率也不高,导致了大量的异常捕获。

为了解决这个问题,编写了一个小型的静态函数,其工作原理类似于PortQry或NMap工具。尝试使用BeginConnect子程序进行连接,然后等待直到超时,假设端口不再响应并将其标记为已过滤。这种方法不仅响应迅速,而且在BackgroundWorker中使用时线程表现良好。

代码实现

以下是该函数的基本实现:

public static SocketResponse SocketPoll( string Node = "127.0.0.1", int tcpPort = 135, int tcpTimeout = 2500 ) { if (Node == null || Node.Trim() == "") Node = "127.0.0.1"; if (tcpPort < 0) tcpPort = 135; if (tcpTimeout < 0) tcpTimeout = 2500; IPAddress ipNode = DetermineIP(Node); TcpClient tSocket = new TcpClient(); DateTime endTime = DateTime.Now.AddMilliseconds(tcpTimeout); IAsyncResult ar = tSocket.BeginConnect(ipNode, tcpPort, null, tSocket); while (DateTime.Now < endTime) { if (ar.IsCompleted) { Socket s = tSocket.Client; try { if (!s.Poll(100, SelectMode.SelectError)) { return SocketResponse.LISTENING; } s.EndConnect(ar); tSocket.Close(); } catch (System.Net.Sockets.SocketException SocketEx) { switch ((SocketError)Enum.ToObject(typeof(SocketError), SocketEx.ErrorCode)) { case SocketError.ConnectionRefused: return SocketResponse.NOT_LISTENING; case SocketError.HostUnreachable: case SocketError.HostDown: case SocketError.NetworkUnreachable: return SocketResponse.UNREACHABLE; default: return SocketResponse.OTHER; } } } Thread.Sleep(10); } return SocketResponse.FILTERED; }

在上述代码中,首先对输入参数进行了校验和默认值设置。然后,创建了一个TcpClient实例,并使用BeginConnect方法尝试异步连接到指定的IP地址和端口。设置了一个结束时间,如果在指定的超时时间内连接完成,检查连接状态并相应地返回结果。如果在超时时间内没有完成连接,返回FILTERED状态。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485