我似乎无法找到任何告诉我路由器中的端口是否打开的信息。 这甚至可能吗?
我现在的代码似乎并没有真正起作用......
private void ScanPort()
{
string hostname = "localhost";
int portno = 9081;
IPAddress ipa = (IPAddress) Dns.GetHostAddresses(hostname)[0];
try
{
System.Net.Sockets.Socket sock =
new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp);
sock.Connect(ipa, portno);
if (sock.Connected == true) // Port is in use and connection is successful
MessageBox.Show("Port is Closed");
sock.Close();
}
catch (System.Net.Sockets.SocketException ex)
{
if (ex.ErrorCode == 10061) // Port is unused and could not establish connection
MessageBox.Show("Port is Open!");
else
MessageBox.Show(ex.Message);
}
}
答案 0 :(得分:34)
试试这个:
using(TcpClient tcpClient = new TcpClient())
{
try {
tcpClient.Connect("127.0.0.1", 9081);
Console.WriteLine("Port open");
} catch (Exception) {
Console.WriteLine("Port closed");
}
}
您应该将127.0.0.1更改为192.168.0.1或路由器的IP地址。
答案 1 :(得分:19)
更好的解决方案,您甚至可以指定超时:
bool IsPortOpen(string host, int port, TimeSpan timeout)
{
try
{
using(var client = new TcpClient())
{
var result = client.BeginConnect(host, port, null, null);
var success = result.AsyncWaitHandle.WaitOne(timeout);
if (!success)
{
return false;
}
client.EndConnect(result);
}
}
catch
{
return false;
}
return true;
}
而且,在F#中:
let IsPortOpen (host: string, port: int, timeout: TimeSpan): bool =
let canConnect =
try
use client = new TcpClient()
let result = client.BeginConnect(host, port, null, null)
let success = result.AsyncWaitHandle.WaitOne(timeout)
match success with
| false -> false
| true ->
client.EndConnect(result)
true
with
| _ -> (); false
canConnect
答案 2 :(得分:3)
如果您要连接到loopback adapter - localhost
或127.0.0.1
(there's no place like 127.0.0.1!),则不太可能会转到路由器。操作系统很聪明,可以识别出它是一个特殊的地址。如果您确实指定机器的“真实”IP地址,那么Dunno也是如此。
另请参阅此问题:What is the purpose of the Microsoft Loopback Adapter?
另请注意,在Windows中运行traceroute localhost
(tracert localhost
)表明所涉及的唯一网络节点是您自己的计算机。路由器永远不会参与其中。
答案 3 :(得分:2)
无法知道端口是否在您的路由器中转发,除非该端口中有程序正在侦听。
正如您在克林顿的回答中所看到的,正在使用的.Net类是TcpClient,这是因为您正在使用TCP套接字进行连接。这就是操作系统建立连接的方式:使用套接字。但是,路由器只是将数据包(OSI模型的第3层)转发或转出。在你的情况下,你的路由器正在做什么叫做:NAT。它是由一个或多个私有IP共享的一个公共IP。这就是你进行端口转发的原因。
数据包路径中可能有很多路由器,你永远不会知道发生了什么。
假设您以传统方式发送信件。也许你可以在信中写下接收者必须回答你的信,以便检查他/她是否在那里(你和接收者是插座)。如果您收到答案,您将确定他/她在那里,但如果您没有收到任何东西,您不知道邮递员(在您的情况下是路由器)是否忘记发送信件,或接收器没有回答。你也永远不知道邮递员是否已经要求朋友发送那封信。此外,邮件员不会打开信件,以便知道他/她可能会回答,因为您正在等待回复。你所要做的就是等一段时间才能收到答案。如果你在那个时期没有收到任何东西,你会认为接收者不是你发的信。那是一个“超时”。
我看到了一个提到nmap软件的答案。这真的是一个非常好的和复杂的软,但我认为它将以相同的方式工作。如果该端口没有应用程序侦听,则无法知道它是否已打开。
如果我很清楚,请告诉我。
答案 4 :(得分:1)
路由器上的前向端口无法从局域网内部进行测试,您需要从WAN(Internet)端连接以查看端口转发是否正常工作。
多个互联网站点提供服务以检查端口是否已打开:
如果要使用自己的代码进行检查,则需要确保通过外部代理重新路由TCP / IP连接或设置隧道。这与您的代码无关,它是基本的网络101。
答案 5 :(得分:1)
public static bool PortInUse(int port)
{
bool inUse = false;
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint [] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach(IPEndPoint endPoint in ipEndPoints)
{
if(endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
答案 6 :(得分:0)
对我来说,在端口连接可用或经过一定的重试后,我需要阻塞。所以,我想出了这段代码:
public bool IsPortOpen(string host, int port, int timeout, int retry)
{
var retryCount = 0;
while (retryCount < retry)
{
if (retryCount > 0)
Thread.Sleep(timeout);
try
{
using (var client = new TcpClient())
{
var result = client.BeginConnect(host, port, null, null);
var success = result.AsyncWaitHandle.WaitOne(timeout);
if (success)
return true;
client.EndConnect(result);
}
}
catch
{
// ignored
}
finally { retryCount++; }
}
return false;
}
希望这有帮助!
答案 7 :(得分:0)
public string GetAvailablePort()
{int startingPort=1000;
string portnumberinformation = string.Empty;
IPEndPoint[] endPoints;
List<int> portArray = new List<int>();
IPGlobalPr`enter code here`operties properties = IPGlobalProperties.GetIPGlobalProperties();`enter code here`
//getting active tcp listners
endPoints = properties.GetActiveTcpListeners();
portArray.AddRange(from n in endPoints
where n.Port >= startingPort
select n.Port);
portArray.Sort();
for (int i = 0; i < portArray.Count; i++)
{
if (check condition)
{
do somting
}
}
return portnumberinformation;
}
答案 8 :(得分:0)
除了BeginConnect之外,您还可以使用ConnectAsync(我认为是在.NET Framework 4.5中添加的)。
TcpClient client = null;
try {
client = new TcpClient();
var task = client.ConnectAsync(host, port);
if (task.Wait(timeout)) {//if fails within timeout, task.Wait still returns true.
if (client.Connected) {
// port reachable
}
else
// connection refused probably
}
else
// timed out
}
catch (Exception ex) {
// connection failed
}
finally {
client.Close();
}
完整项目为here,因为paping拒绝运行,而且我找不到喜欢的其他“ ping host:port”工具。
答案 9 :(得分:-2)
如果它是路由器,则是通过
之类的在线服务进行检查的最简单方法您还可以尝试使用 telenet 来检查端口是否可访问
telenet [ip-address] [port]