C# Undefinierbarer Tcp-Socket Fehler

Rooky420

Cadet 4th Year
Registriert
Nov. 2015
Beiträge
98
Hallo Community,

Ich habe ein Problem mit System.Net.Sockets, dass ich noch nie bisher hatte.
Ich habe schon einige Testprogramme zu Sockets erstellt die bisher alle funktioniert haben. Jetzt wollte ich einfach mal eine gute "Networking.dll" erstellen damit ich es möglichst einfach in alle möglichen Programme einbinden kann.
Diese Dll soll eine 1 zu 1 Verbindung in einem Lokalen Netzwerk bereitstellen.

Es tritt Folgender Fehler auf:
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll

Additional information: Normalerweise darf jede Socketadresse (Protokoll, Netzwerkadresse oder Anschluss) nur jeweils einmal verwendet werden

Ich hatte so ein Problem noch nie.

Server:
Code:
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, _port));

Client:
Code:
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
...
//Das ist dann in einem anderen Thread
_clientSocket.Connect(ipserver, _port);

ipserver ist immer eine instanz aus System.Net.IPAddress mit 127.0.0.1
und _port ist immer 61234

Könnt ihr mir helfen den Fehler zu finden?

Mfg,
Rooky420
 
1. Breakpoint auf _serverSocket.Bind - Methode setzen und schauen ob sie mehrmals aufgerufen wird
2. mit netstat schauen ob der Port bereits geöffnet ist
3. Schauen ob das Serverprogramm mehrmals gestartet wird.

Die "Additional information" ist doch ziemlich eindeutig. Es kann nur ein Socket gleichzeitig an einen Port gebunden werden.

EDIT: Mir fällt grad noch eine andere Sache dazu ein. Ich hatte kürzlich ein ähnliches Problem an einem Rechner. Da war die Ursache nicht, dass der Port bereits geöffnet war, sondern dass er zwar geschlossen wurde, vom System aber noch nicht wieder für weitere Verbindungen freigegeben wurde.
FIN_WAIT2 war da der Portstatus (einsehbar über netstat)
 
Zuletzt bearbeitet:
Hallo,

zu dem von dir beschriebenen Fehler kann ich leider auch keine Auskunft geben.
Wenn es dir aber nur darum geht eine tcp Verbindung zwischen einem Client und einem Server
herzustellen, dann kann ich dir hier mal meinen code dazu posten.

Wurde bei mir schon mehrmals getestet und verwendet:

Server Seite:
Code:
int tcpPort = 11001;

TcpListener server = new TcpListener(IPAddress.Any, tcpPort);
server.Start();

Client Seite:
Code:
int tcpPort = 11001;
IPAddress serverIP = //Your server ip

TcpClient client = new TcpClient(AddressFamily.InterNetwork);
var result = client.BeginConnect(serverIP, tcpPort, null, null);
var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2));

//Connection failed
if (!success)
{
    return;
}

//Connection build
client.EndConnect(result);

Um die Verbindung auf der Server Seite anzunehmen, musst du einen Thread anlegen, der regelmäßig
prüft, ob ein Verbindungsaufbau aussteht:

Server Seite:
Code:
if (server.Pending())
{
    TcpClient client = server.AcceptTcpClient();
}

Wenn alles klappt hast du dann eine tcp Verbindung aufgebaut und kannst anfangen Daten zu übermitteln.
Falls du dafür auch ein paar code Schnipsel gebrauchen kannst, sag einfach bescheid, dann schreib ich dazu auch noch was.

Grüße T2xlc
 
Hallo Zusammen,

Ich habe einen Bugfix gefunden aber einen den ich eigentlich nicht hernehmen will.

Unten der Code.

Das ist jetzt meine aktuelle ConnectionClient Klasse diese ist so quasi der Client der sich dann auf den Host verbindet.
Das Problem ist das Verbinden an sich.
Wenn ich mit "private bool ConnectSocket(IPAddress ipserver)" die Verbindung aufbaue funktioniert alles einwandfrei jedoch funktioniert es nicht wenn ich die Methode "private async Task<bool> ConnectAsync(IPAddress ipserver)" verwende.
Im grunde machen beide Methoden das Selbe nur, dass ConnectAsync die Verbindungsschleife, die immer wieder versucht zu Verbinden Asynchron aufruft. Dies soll auch das Ziel sein da wenn ich es Synchron aufrufe Hängt sich ja die Anwendung auf bis eine Verbindung Hergestellt wurde. Das ist natürlich nicht schön.

Code:
public ConnectionClient(String IPorName, int Port) : base()
        {
            this._port = Port;
            bool isIP = IPAddress.TryParse(IPorName.Trim(), out _ipAdress);
            if(!isIP)
                _ipAdress = Dns.GetHostEntry(IPorName).AddressList[0];
        }

        public bool Connect()
        {
            _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //bool connect = ConnectAsync(_ipAdress).Result;
            bool connect = ConnectSocket(_ipAdress);
            Connected(connect);
            return connect;
        }

        private async Task<bool> ConnectAsync(IPAddress ipserver)
        {
            return await Task.Factory.StartNew(() => LoopConnect(ipserver));
        }

        private bool ConnectSocket(IPAddress ipserver)
        {
            return LoopConnect(ipserver);
        }

        private bool LoopConnect(IPAddress ipserver)
        {
            int attempts = 0;
            while (!_clientSocket.Connected)
            {
                try
                {
                    attempts++;
                    _clientSocket.Connect(ipserver, _port);
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                if (attempts >= 10 && !_clientSocket.Connected)
                    return false;
            }
            return false;
        }

Wisst Ihr was ich falsch mache?
Die anwendung hängt sich einfach komplett in der ConnectAsync Methode auf.
Der Fehler vorher war dass der Port schon belegt war ich nutze jetzt einen anderen. Danke an DocWindows netstat hat geholfen.
Ich hoffe ihr könnt mir helfen meine ursprüngliche lösung zu verwenden.

Lg,
Rooky420
 
ConnectAsync kann doch gar nicht asynchron laufen wenn du direkt einen Rückgabewert von der Methode erwartest.
Die Hautthread muss so oder so immer warten bis der Connect durch ist. Oder bin ich da grad auf dem Holzweg?
 
Hallo DocWindows,

tut mir leid ich habe es falsch formuliert.
Natürlich läuft es so auch nicht "direkt" Asynchron das ist gewollt so jedoch werden so nicht die Ressourcen des Hauptthreads verbraucht und z.B. eine Form kann immernoch Events und so bearbeiten.
Das Problem ist aber der Fehler. Ich verstehe nicht warum es sich da aufhängt.

mfg
Rooky420
 
DocWindows schrieb:
ConnectAsync kann doch gar nicht asynchron laufen wenn du direkt einen Rückgabewert von der Methode erwartest.
Die Hautthread muss so oder so immer warten bis der Connect durch ist. Oder bin ich da grad auf dem Holzweg?

Nee, bist du nicht.
Ich hab in den letzten Jahren gerade bei Auslagerung von Aufgaben in andere Threads in C# so den Überblick verloren, weil es da mittlerweile mindestens 5 Methoden gibt, die sich sowohl ergänzen sollen als auch direkte Weiterentwicklungen sind, aber du liegst korrekt.
Hier wird entweder Müll ausgegeben (davon ausgehend, dass Result einfach ein Zeiger auf das eventuelle in der Zukunft fertig gestellte Resultat geben soll), oder es wird gejoint.
Ich sehe in der gegebenen Implementierung keine Schwächen, außer, dass du scheinbar die Nebenläufigkeit von Programmen nicht richtig verstanden hast. In der Tat sollte der Code so "laufen", es scheint, als wäre der Fehler außerhalb (du gibst ja nicht das ganze Projekt her bzw. nicht einmal die Basisklasse).
Im besten Falle wird da einfach false zurückgegeben beim asynchronen Aufruf (weil Standardwert) und du versuchst dich außerhalb nochmal neu zu verbinden (sei es automatisch oder du klickst per GUI nochmals drauf).
 
Zurück
Oben