C# 检查端口是否打开
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11837541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if a port is open
提问by Yuki Kutsuya
I can't seem to find anything that tells me if a port in my router is open or not. Is this even possible?
我似乎找不到任何可以告诉我路由器中的端口是否打开的信息。这甚至可能吗?
The code I have right now doesn't really seem to work...
我现在拥有的代码似乎并没有真正起作用......
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);
}
}
回答by Clinton Ward
Try this:
尝试这个:
using(TcpClient tcpClient = new TcpClient())
{
try {
tcpClient.Connect("127.0.0.1", 9081);
Console.WriteLine("Port open");
} catch (Exception) {
Console.WriteLine("Port closed");
}
}
You should probably change 127.0.0.1 to something like 192.168.0.1 or whatever your router's IP address is.
您可能应该将 127.0.0.1 更改为 192.168.0.1 或任何路由器的 IP 地址。
回答by Nicholas Carey
If you're connecting to the loopback adapter— localhostor 127.0.0.1(there's no place like 127.0.0.1!), you're unlikely to ever go out to the router. The OS is smart enough to recognize that it's a special address. Dunno if that holds true as well if you actually specify your machine's "real" IP address.
如果您连接到环回适配器—localhost或者127.0.0.1(没有像 127.0.0.1 这样的地方!),您不太可能去路由器。操作系统足够聪明,可以识别它是一个特殊地址。不知道如果您实际指定了机器的“真实”IP 地址,这是否也成立。
See also this question: What is the purpose of the Microsoft Loopback Adapter?
另请参阅此问题:Microsoft Loopback Adapter 的用途是什么?
Also note that running traceroute localhost(tracert localhostin Windows) shows that the only network node involved is your own machine. The router is never involved.
另请注意,运行traceroute localhost(tracert localhost在 Windows 中)表明唯一涉及的网络节点是您自己的机器。从不涉及路由器。
回答by Antoine Megens
A port forward on the router cannot be tested from inside the LAN, you need to connect from the WAN (internet) side to see if a port forward is working or not.
路由器上的端口转发无法从 LAN 内部测试,您需要从 WAN(互联网)端连接以查看端口转发是否正常工作。
Several internet sites offer services to check if a port is open:
一些 Internet 站点提供检查端口是否打开的服务:
If you want to check with your own code, then you need to make sure the TCP/IP connection is rerouted via an external proxy or setup a tunnel. This has nothing to do with your code, it's basic networking 101.
如果要检查自己的代码,则需要确保 TCP/IP 连接通过外部代理重新路由或设置隧道。这与您的代码无关,它是基本网络 101。
回答by ympostor
A better solution where you can even specify a timeout:
一个更好的解决方案,您甚至可以指定超时:
using System;
using System.Net.Sockets;
// ...
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);
client.EndConnect(result);
return success;
}
}
catch
{
return false;
}
}
And, in F#:
而且,在 F# 中:
open System
open System.Net.Sockets
let isPortOpen (host: string) (port: int) (timeout: TimeSpan): bool =
try
use client = new TcpClient()
let result = client.BeginConnect(host, port, null, null)
let success = result.AsyncWaitHandle.WaitOne timeout
client.EndConnect result
success
with
| _ -> false
let available = isPortOpen "stackoverflow.com" 80 (TimeSpan.FromSeconds 10.)
printf "Is stackoverflow available? %b" available
回答by Ignacio
There is no way to know if the port is forwarded in your router, except if there is a program listening on that port.
没有办法知道该端口是否在您的路由器中转发,除非有程序在该端口上侦听。
As you may see in the Clinton answer, the .Net class being used is TcpClient and that is because you are using a TCP socket to connect to. That is the way operating systems make connections: using a socket. However, a router just forwards the packets (layer 3 of the OSI Model) in or out. In your case, what your router is doing is called: NAT. It is one public IP shared by a one or more private IPs. That′s why you are making a port forwarding.
正如您在克林顿的回答中看到的那样,正在使用的 .Net 类是 TcpClient,这是因为您正在使用 TCP 套接字进行连接。这就是操作系统建立连接的方式:使用套接字。但是,路由器只是将数据包(OSI 模型的第 3 层)转发出去或转发出去。在您的情况下,您的路由器正在执行的操作称为:NAT。它是由一个或多个私有 IP 共享的一个公共 IP。这就是您进行端口转发的原因。
There may be a lot of routers in the path of the packets, and you will never know what had happened.
数据包的路径中可能有很多路由器,你永远不会知道发生了什么。
Let′s imagine you are sending a letter in the traditional way. Perhaps you can write in the letter that the receiver must answer, in order to check he/she is there (you and the receiver are the sockets). If you receive an answer you will be sure he/she is there, but if you don′t receive anything you don′t know if the mailman (in your case the router) forgot to deliver the letter, or the receiver hadn′t answered. You would also never know if the mailman has asked a friend to deliver that letter. Moreover, the mailman won′t open the letter in order to know he/she may answer because you are waiting for a reply. All you may do is wait some time to receive the answer. If you don′t receive anything in that period you will assume that the receiver isn′t where you sent the letter. That is a "timeout".
假设您正在以传统方式发送一封信。或许您可以在信中写下接收者必须回答的内容,以检查他/她是否在那里(您和接收者是插座)。如果您收到答复,您将确定他/她在那里,但如果您没有收到任何东西,您不知道是邮递员(在您的情况下是路由器)忘记投递信件,还是收件人没有投递回答。您也永远不会知道邮递员是否要求朋友递送那封信。此外,邮递员不会打开信件,以知道他/她可能会回复,因为您正在等待回复。您所能做的就是等待一段时间才能收到答案。如果在那段时间内您没有收到任何东西,您将假定收件人不是您发送信件的地方。那就是“超时”。
I saw an answer mentioning the nmap software. It′s really a very good and complex soft, but I think it will work in the same way. If there is no app listening in that port, there is no way to know if it is open or not.
我看到一个提到 nmap 软件的答案。这真的是一个非常好的和复杂的软,但我认为它会以同样的方式工作。如果没有应用程序在该端口侦听,则无法知道它是否打开。
Please, let me know if I was clear.
请让我知道我是否清楚。
回答by Mathieu Paquette
For me, I needed something blocking until the connection to the port is available or after a certain amount of retries. So, I figured out this code:
对我来说,我需要一些阻塞,直到与端口的连接可用或经过一定数量的重试之后。所以,我想出了这个代码:
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;
}
Hope this helps!
希望这可以帮助!
回答by Ravi Kumar G N
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;
}
回答by user11415274
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;
}
回答by geekonweb
If it is Router the simplest way to check it through online services like
如果是路由器,则是通过在线服务进行检查的最简单方法,例如
You can also try using telenetto chek wether port is accessible or not
您也可以尝试使用Telenet来检查端口是否可以访问
telenet [ip-address] [port]

