C #에서 TcpClient를 사용하거나 일반적으로 소켓에 연결하려면 내 컴퓨터에서 특정 포트가 사용 가능한지 먼저 확인하려면 어떻게해야합니까?
추가 정보 : 이것은 내가 사용하는 코드입니다.
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
C #에서 TcpClient를 사용하거나 일반적으로 소켓에 연결하려면 내 컴퓨터에서 특정 포트가 사용 가능한지 먼저 확인하려면 어떻게해야합니까?
추가 정보 : 이것은 내가 사용하는 코드입니다.
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
답변:
를 사용하고 있으므로 TcpClient
열린 TCP 포트를 확인하고 있음을 의미합니다. System.Net.NetworkInformation 네임 스페이스 에서 사용할 수있는 좋은 개체가 많이 있습니다 .
IPGlobalProperties
개체를 사용하여 개체 배열에 TcpConnectionInformation
도달하면 끝점 IP 및 포트에 대해 조사 할 수 있습니다.
int port = 456; //<--- This is your value
bool isAvailable = true;
// Evaluate current system tcp connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
{
if (tcpi.LocalEndPoint.Port==port)
{
isAvailable = false;
break;
}
}
// At this point, if isAvailable is true, we can proceed accordingly.
netstat -a -b
. 에는 LISTENING
연결이 없습니다 GetActiveTcpConnections()
. 또한 System.Net.IPEndPoints[]
반환 된 체크인을해야합니다ipGlobalProperties.GetActiveTcpListeners();
Intertube의 끝이 잘못되었습니다. 특정 포트를 하나만 열 수있는 서버입니다. 일부 코드 :
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
try {
TcpListener tcpListener = new TcpListener(ipAddress, 666);
tcpListener.Start();
}
catch (SocketException ex) {
MessageBox.Show(ex.Message, "kaboom");
}
실패 :
일반적으로 각 소켓 주소 (프로토콜 / 네트워크 주소 / 포트)를 한 번만 사용할 수 있습니다.
TCP 연결을 설정할 때 4- 튜플 (source-ip, source-port, dest-ip, dest-port)은 고유해야합니다. 이는 패킷이 올바른 위치로 전달되도록하기위한 것입니다.
서버 측에는 하나의 서버 프로그램 만 들어오는 포트 번호에 바인딩 할 수 있다는 추가 제한이 있습니다 (하나의 IP 주소를 가정하면 다중 NIC 서버에는 다른 권한이 있지만 여기서 논의 할 필요는 없습니다).
따라서 서버 측에서 다음을 수행합니다.
클라이언트 측에서는 일반적으로 조금 더 간단합니다.
대상 IP / 포트가 고유 할 필요 는 없습니다. 그럴 경우 한 번에 한 사람 만 Google을 사용할 수 있고 비즈니스 모델이 거의 파괴 될 수 있기 때문입니다.
즉, 소스 포트가 유일한 차이점 인 여러 세션을 설정하여 청크를 병렬로 다운로드 할 수 있기 때문에 다중 세션 FTP와 같은 놀라운 일을 할 수도 있습니다. 급류는 일반적으로 각 세션의 목적지가 다르다는 점에서 약간 다릅니다.
그리고 그 모든 혼란스러운 (죄송합니다), 특정 질문에 대한 대답은 자유 포트를 지정할 필요가 없다는 것입니다. 소스 포트를 지정하지 않는 호출로 서버에 연결하는 경우 거의 확실하게 커버 아래에서 0을 사용하고 시스템에서 사용하지 않는 포트를 제공합니다.
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
... 컴퓨터에서 특정 포트가 사용 가능한지 어떻게 먼저 확인할 수 있습니까?
다른 응용 프로그램에서 사용하지 않음을 의미합니다. 응용 프로그램이 포트를 사용하는 경우 다른 사용자는 포트가 해제 될 때까지 사용할 수 없습니다. – 알리
여기서 무슨 일이 일어나고 있는지 오해했습니다.
TcpClient (...) 매개 변수는 연결하려는 서버 IP 및 서버 포트입니다.
TcpClient는 사용 가능한 풀에서 임시 로컬 포트를 선택하여 서버와 통신합니다. winsock 계층에 의해 자동으로 처리되므로 로컬 포트의 가용성을 확인할 필요가 없습니다.
위의 코드 조각을 사용하여 서버에 연결할 수없는 경우 문제는 여러 가지 중 하나 이상일 수 있습니다. (예 : 서버 IP 및 / 또는 포트가 잘못되었거나 원격 서버를 사용할 수 없음 등)
이 팁에 감사드립니다. 동일한 기능이 필요했지만 서버 측에서 포트가 사용 중인지 확인하기 위해이 코드를 수정했습니다.
private bool CheckAvailableServerPort(int port) {
LOG.InfoFormat("Checking Port {0}", port);
bool isAvailable = true;
// Evaluate current system tcp connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();
foreach (IPEndPoint endpoint in tcpConnInfoArray) {
if (endpoint.Port == port) {
isAvailable = false;
break;
}
}
LOG.InfoFormat("Port {0} available = {1}", port, isAvailable);
return isAvailable;
}
-anb
)를 사용하여 애플리케이션의 PID를 제공하는 것과 동일한 정보를 제공 하지 않으며 매개 변수없이 외부 연결과 상태를 표시합니다.
답변 jro에 감사드립니다. 내 용도에 맞게 조정해야했습니다. 포트가 수신 대기 중인지, 필요하지 않은지 확인해야했습니다. 이를 위해 나는 대체
TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
와
IPEndPoint[] objEndPoints = ipGlobalProperties.GetActiveTcpListeners();.
내 포트 값을 찾을 수 없는지 확인하는 끝점 배열을 반복했습니다.
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);
}
netstat! Windows와 함께 제공되는 네트워크 명령 줄 유틸리티입니다. 현재 설정된 모든 연결과 현재 수신중인 모든 포트를 표시합니다. 이 프로그램을 사용하여 확인할 수 있지만 코드에서이 작업을 수행하려면 System.Net.NetworkInformation 네임 스페이스를 살펴보십시오. 2.0부터 새로운 네임 스페이스입니다. 거기에 몇 가지 좋은 점이 있습니다. 그러나 결국 netstat 명령을 통해 사용할 수있는 동일한 종류의 정보를 얻으려면 P / Invoke로 결과를 얻어야합니다.
이 네임 스페이스에는 네트워크에 대한 정보를 파악하는 데 사용할 수있는 여러 클래스가 포함되어 있습니다.
나는 그 오래된 코드를 찾을 수 없었지만 비슷한 것을 직접 작성할 수 있다고 생각합니다. 좋은 시작은 IP Helper API 를 확인하는 것 입니다. GetTcpTable WINAPI 기능에 대한 Google MSDN을 사용하고 P / Invoke를 사용하여 필요한 정보를 얻을 때까지 열거합니다.
당신은 말한다
다른 응용 프로그램에서 사용하지 않음을 의미합니다. 응용 프로그램이 포트를 사용하는 경우 다른 사용자는 포트가 해제 될 때까지 사용할 수 없습니다.
그러나 다른 사람들이 거기에서 듣고 있다면 항상 포트에 연결할 수 있습니다. 그렇지 않으면 http 포트 80이 엉망이 될 것입니다.
귀하의
c = new TcpClient(ip, port);
실패하면 아무것도 듣고 있지 않습니다. 그렇지 않으면 다른 컴퓨터 / 응용 프로그램에 해당 IP 및 포트에 대한 소켓이 열려 있어도 연결됩니다.
ipGlobalProperties.GetActiveTcpConnections()
수신 상태에서 연결을 반환하지 않습니다.
포트는 청취에 사용할 수 있지만 아무도 연결하지 않으면 위에서 설명한 방법이 작동하지 않습니다.
사용 가능한 포트에서 제외합니다.
다음 가져 오기 :
using System.Net.NetworkInformation;
다음 기능을 사용하여 포트의 사용 가능 여부를 확인할 수 있습니다.
private bool isPortAvalaible(int myPort)
{
var avalaiblePorts = new List<int>();
var properties = IPGlobalProperties.GetIPGlobalProperties();
// Active connections
var connections = properties.GetActiveTcpConnections();
avalaiblePorts.AddRange(connections);
// Active tcp listners
var endPointsTcp = properties.GetActiveTcpListeners();
avalaiblePorts.AddRange(endPointsTcp);
// Active udp listeners
var endPointsUdp = properties.GetActiveUdpListeners();
avalaiblePorts.AddRange(endPointsUdp);
foreach (int p in avalaiblePorts){
if (p == myPort) return false;
}
return true;
}
VB.NET 을 사용하는 사람들에게 비슷한 기능을 제공합니다 .
Imports System.Net.NetworkInformation
Private Function isPortAvalaible(ByVal myPort As Integer) As Boolean
Dim props As IPGlobalProperties = IPGlobalProperties.GetIPGlobalProperties()
' ignore active connections
Dim tcpConnInfoArray() As TcpConnectionInformation = props.GetActiveTcpConnections()
For Each tcpi As Net.NetworkInformation.TcpConnectionInformation In tcpConnInfoArray
If tcpi.LocalEndPoint.Port = myPort Then
Return False
End If
Next tcpi
' ignore active TCP listeners
Dim activeTcpListeners() As Net.IPEndPoint = props.GetActiveTcpListeners
For Each tcpListener As Net.IPEndPoint In activeTcpListeners
If tcpListener.Port = myPort Then
Return False
End If
Next tcpListener
' ignore active UPD listeners
Dim activeUdpListeners() As Net.IPEndPoint = props.GetActiveUdpListeners
For Each udpListener As Net.IPEndPoint In activeUdpListeners
If udpListener.Port = myPort Then
Return False
End If
Next udpListener
Return True
End Function
dotnet core 3.1에서 사용 가능한 포트 (내 단위 테스트에서 필요한 것)를 찾는 정확한 질문에 답하기 위해 다음을 찾았습니다.
public static int GetAvailablePort(IPAddress ip) {
TcpListener l = new TcpListener(ip, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
Log.Info($"Available port found: {port}");
return port;
}
참고 : 나는 검색과 발견 포트 제로에 대해 @ user207421하여 주석 기반 이 살짝 수정합니다.
일부 원격 TCP 서비스에 연결하기 위해 로컬 컴퓨터에서 어떤 포트가 열려 있는지 알 필요가 없습니다 (특정 로컬 포트를 사용하려는 경우는 아니지만 일반적으로 그렇지 않음).
모든 TCP / IP 연결은 원격 IP, 원격 포트 번호, 로컬 IP, 로컬 포트 번호의 4 가지 값으로 식별되지만 연결을 설정하려면 원격 IP와 원격 포트 번호 만 알면됩니다.
다음을 사용하여 tcp 연결을 만들 때
TcpClient c; c = 새 TcpClient (remote_ip, remote_port);
시스템은 연결에 사용 가능한 여러 로컬 포트 번호 중 하나를 자동으로 할당합니다. 아무것도 할 필요가 없습니다. 원격 포트가 열려 있는지 확인할 수도 있습니다. 하지만 연결을 시도하는 것보다 더 좋은 방법은 없습니다.
public static bool TestOpenPort(int Port)
{
var tcpListener = default(TcpListener);
try
{
var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
tcpListener = new TcpListener(ipAddress, Port);
tcpListener.Start();
return true;
}
catch (SocketException)
{
}
finally
{
if (tcpListener != null)
tcpListener.Stop();
}
return false;
}
test_connection("ip", port);
public void test_connection(String hostname, int portno) {
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) {
MessageBox.Show("Port is in use");
}
sock.Close();
}
catch (System.Net.Sockets.SocketException ex) {
if (ex.ErrorCode == 10060) {
MessageBox.Show("No connection.");
}
}
}