[C#] C #에서 TCP 포트를 사용할 수 있는지 확인하는 방법은 무엇입니까?

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.


답변

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 주소와 포트를 지정 합니다 . 그것은 수있는 소스 포트를 지정하지만, 일반적으로 자동에게 무료로 포트를 할당 시스템의 제로하는 결과를 사용합니다.

대상 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;
}


답변

답변 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);
}