Wie kann ich in C # einen TcpClient verwenden oder allgemein eine Verbindung zu einem Socket herstellen?
Weitere Informationen: .__ Dies ist der Code, den ich verwende:
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
Da Sie eine TcpClient
verwenden, überprüfen Sie die offenen TCP - Ports. Im Namespace System.Net.NetworkInformation sind viele gute Objekte verfügbar.
Verwenden Sie das IPGlobalProperties
-Objekt, um zu einem Array von TcpConnectionInformation
-Objekten zu gelangen, das Sie dann nach Endpunkt-IP und -Port abfragen können.
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.
Sie befinden sich am falschen Ende des Intertube. Es ist der Server, an dem nur ein bestimmter Port geöffnet sein kann. Etwas code:
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
try {
TcpListener tcpListener = new TcpListener(ipAddress, 666);
tcpListener.Start();
}
catch (SocketException ex) {
MessageBox.Show(ex.Message, "kaboom");
}
Schlägt fehl mit:
Normalerweise ist nur eine Verwendung jeder Socket-Adresse (Protokoll/Netzwerkadresse/Port) zulässig.
Wenn Sie eine TCP -Verbindung einrichten, muss der 4-Tuple (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port) eindeutig sein. Dadurch wird sichergestellt, dass Pakete an die richtige Stelle gesendet werden.
Auf der Seite Server gibt es eine weitere Einschränkung, dass nur ein Serverprogramm an eine eingehende Portnummer gebunden werden kann (unter der Annahme einer IP-Adresse; Multi-NIC-Server haben andere Fähigkeiten, aber wir müssen sie hier nicht diskutieren ).
Also auf der Serverseite:
Auf der Clientseite ist es normalerweise etwas einfacher:
Es ist no Voraussetzung, dass die Ziel-IP/der Zielport eindeutig sein muss, da dann jeweils nur eine Person Google verwenden kann und das Geschäftsmodell dadurch völlig zerstört wird.
Dies bedeutet, dass Sie sogar so wundersame Dinge tun können, wie z. B. das Multi-Session-FTP-Verfahren, da Sie mehrere Sitzungen einrichten, bei denen der einzige Unterschied der Quellport ist, sodass Sie Chunks parallel herunterladen können. Torrents unterscheiden sich insofern, als das Ziel jeder Sitzung normalerweise unterschiedlich ist.
Nach all dem Trübsal (Entschuldigung) lautet die Antwort auf Ihre spezifische Frage, dass Sie keinen freien Port angeben müssen. Wenn Sie eine Verbindung zu einem Server herstellen, bei dem der Quellport nicht angegeben ist, wird fast immer Null unter den Deckblättern verwendet, und das System gibt Ihnen einen ungenutzten.
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
Wie kann ich zuerst prüfen, ob ein bestimmter Port auf meinem Computer frei ist?
Ich meine, dass es von keiner anderen Anwendung verwendet wird. Wenn eine Anwendung einen Port verwendet, können andere ihn nicht verwenden, bis er frei wird. - ALi
Sie haben missverstanden, was hier passiert.
TcpClient (...) -Parameter beziehen sich auf die Server-IP-Adresse und den Server-Port, zu dem Sie eine Verbindung herstellen möchten.
Der TcpClient wählt einen transienten lokalen Port aus dem verfügbaren Pool aus, um mit dem Server zu kommunizieren. Es muss nicht nach der Verfügbarkeit des lokalen Ports gesucht werden, da er automatisch vom Winsock-Layer verarbeitet wird.
Falls Sie mit dem obigen Codefragment keine Verbindung zum Server herstellen können, kann es sich um ein oder mehrere Probleme handeln. (d. h. Server-IP und/oder -Port ist falsch, Remote-Server nicht verfügbar usw.)
Danke für diesen Tipp. Ich brauchte die gleiche Funktionalität, aber auf der Serverseite, um zu überprüfen, ob ein Port verwendet wurde. Daher habe ich ihn an diesen Code angepasst.
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;
}
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);
}
danke für die antwort jro. Ich musste es für meinen Gebrauch anpassen. Ich musste überprüfen, ob ein Port abgehört wurde und nicht unbedingt aktiv war. Dafür habe ich ersetzt
TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
mit
IPEndPoint[] objEndPoints = ipGlobalProperties.GetActiveTcpListeners();.
Ich wiederholte das Array von Endpunkten und überprüfte, ob mein Portwert nicht gefunden wurde.
netstat! Dies ist ein Netzwerk-Befehlszeilen-Dienstprogramm, das mit Windows geliefert wird. Es zeigt alle aktuell eingerichteten Verbindungen und alle Ports, die gerade abgehört werden. Sie können dieses Programm verwenden, um dies zu überprüfen, aber wenn Sie dies vom Code aus tun möchten, schauen Sie in den Namespace System.Net.NetworkInformation. Es ist ein neuer Namespace ab 2.0. Es gibt einige gute Sachen dort. Wenn Sie jedoch die gleichen Informationen erhalten möchten, die über den Befehl netstat verfügbar sind, müssen Sie P/Invoke ausführen.
Dieser Namespace enthält eine Reihe von Klassen, die Sie verwenden können, um Dinge über das Netzwerk herauszufinden.
Ich konnte dieses alte Stück Code nicht finden, aber ich denke, dass Sie selbst etwas ähnliches schreiben können. Ein guter Anfang ist das Auschecken der IP Helper API . Google MSDN für die GetTcpTable WINAPI-Funktion, und verwenden Sie P/Invoke zum Auflisten, bis Sie über die erforderlichen Informationen verfügen.
ipGlobalProperties.GetActiveTcpConnections()
gibt keine Verbindungen im Listen-Status zurück.
Port kann für das Abhören verwendet werden, aber wenn keine Verbindung besteht, funktioniert die oben beschriebene Methode nicht.
Wenn ich mich nicht sehr irre, können Sie System.Network.wetwas verwenden, um es zu überprüfen.
Dies führt jedoch immer zu einer Rennbedingung.
Die kanonische Art der Überprüfung besteht darin, diesen Port zu überwachen. Wenn Sie eine Fehlermeldung erhalten, war der Port nicht geöffnet.
Ich denke Dies ist ein Teil des Grunds, warum bind () und listen () zwei getrennte Systemaufrufe sind.
Du sagst
Ich meine, es wird von keinem .__ verwendet. andere Anwendung. Wenn eine Bewerbung verwendet einen Port, den andere nicht verwenden können bis es frei wird.
Sie können jedoch immer eine Verbindung zu einem Port herstellen, während andere ihn verwenden, wenn dort etwas zu hören ist. Ansonsten wäre der HTTP-Port 80 ein Durcheinander.
Wenn dein
c = new TcpClient(ip, port);
scheitert, dann hört nichts dort zu. Andernfalls wird eine Verbindung hergestellt, auch wenn auf einer anderen Maschine/Anwendung ein Socket für diese IP-Adresse und diesen Port vorhanden ist.
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;
}
Seien Sie sich bewusst, dass das Zeitfenster zwischen der Überprüfung und dem Moment, in dem Sie versuchen, eine Verbindung herzustellen, einige Zeit in Anspruch nehmen kann - klassisch TOCTOU . Warum versuchst du nicht einfach, eine Verbindung herzustellen? Wenn dies fehlschlägt, wissen Sie, dass der Port nicht verfügbar ist.
Von den verfügbaren Häfen würde ich ausschließen:
Mit folgendem Import:
using System.Net.NetworkInformation;
Mit der folgenden Funktion können Sie prüfen, ob ein Port verfügbar ist oder nicht:
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;
}
Ich gebe Ihnen eine ähnliche Funktion für diejenigen, die VB.NET verwenden:
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
Sie müssen nicht wissen, welche Ports auf Ihrem lokalen Computer geöffnet sind, um eine Verbindung zu einem entfernten TCP - Dienst herzustellen (es sei denn, Sie möchten einen bestimmten lokalen Port verwenden, dies ist jedoch normalerweise nicht der Fall).
Jede TCP/IP-Verbindung wird durch 4 Werte identifiziert: Remote-IP, Remote-Portnummer, lokale IP-Adresse, lokale Portnummer. Sie müssen jedoch nur Remote-IP und Remote-Portnummer kennen, um eine Verbindung herzustellen.
Beim Erstellen einer TCP-Verbindung mit
TcpClient c; C = neuer TcpClient (remote_ip, remote_port);
Ihr System weist Ihrer Verbindung automatisch eine von vielen freien lokalen Portnummern zu. Sie müssen nichts tun ... Sie möchten vielleicht auch prüfen, ob ein Remote-Port geöffnet ist. Aber es gibt keinen besseren Weg, als nur zu versuchen, eine Verbindung herzustellen.
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.");
}
}
}
Überprüfen Sie den Fehlercode 10048
try
{
TcpListener tcpListener = new TcpListener(ipAddress, portNumber);
tcpListener.Start();
}
catch(SocketException ex)
{
if(ex.ErrorCode == 10048)
{
MessageBox.Show("Port " + portNumber + " is currently in use.");
}
return;
}