Hey @ll,
ich dachte wenn ich mich sowieso gerade damit rumschlage, setzte ich hier mal n kleines Tut rein zum Thema
Asynchrones und Synchrones verbinden mit TcpListener.
Synchrones Verfahren:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| namespace Tutorial { using System; using System.Net; using System.Net.Sockets;
private Class TcpTutorial { static void Main() { TcpClient myClient = AcceptTcpClient(12000); }
private TcpClient AcceptTcpClient(int port) { TcpListener listener = new TcpListener(IPAddress.Any, port);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
listener.Stop();
return client; } } } |
Wie ihr seht ist die synchrone Methode ganz einfach zu realisieren.
Die Portnummer hier ist einfach Zufall. Die Ports und ihre Funktion könnt ihr hier nachschlagen:
www.iana.org
Nun zum etwas komplizierteren Teil:
Asynchrones Verfahren:
Zuerst einmal stellt sich die Frage warum man das ganze überhaupt asynchron abwickeln soll.
Aus einem ganz einfachen Grund: Wenn wir nicht auf einen Clienten warten müssen, oder unsere WindowsForm noch nebenher laufen soll, müssen wir auf die Asynchrone Variante zurückgreifen, da sonst die
AcceptTcpClient()-Metode unser komplettes Programm - oder zumindest den Hauptthread - blockiert.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| namespace Tutorial { using System; using System.Net; using System.Net.Sockets;
private Class TcpTutorial { private TcpClient myClient;
static void Main() { StartAsyncAccepting(12000); }
private void StartAsyncAccepting(int port) { TcpListener listener = new TcpListener(IPAddress.Any, port); listener.Start(); listener.BeginAcceptTcpClient(AsyncAcceptingCallback, listener); }
private void ListenerAcceptingCallback(IAsyncResult state) { TcpListener listener = (TcpListener)state.AsyncState; TcpClient client = listener.EndAcceptTcpClient(state); listener.Stop(); myClient = client; } } } |
Nun zur Erklärung:
TcpListener.BeginnAcceptTcpClient(AsyncCallback callback, IAsyncResult result) Bei diesem Aufruf startet ein neuer Hintergrundthread mit der Instanz des aktuellen TcpListeners (hier:
listener) und wartet auf einen eingehenden Verbindungsversuch.
Das
AsyncCallback ist unsere Methode, die aufgerufen wird sobald eine Anfrage da ist und
IAsyncResult ist ein Objekt, das Informationen zum aktuellen Verbindungsversuch beinhaltet. Im Klartext: die Instanz unseres TcpListeners.
So. Wenn jetzt eine Verbindungsanfrage ankommt, wird unsere Callback-Methode ausgelöst (hier:
ListenerAcceptingCallback).
Das IAsyncResult in der Parameterliste ist zwingend notwendig, da hier die Instanz des TcpListeners übergeben wird. Außerdem akzeptiert
BeginAcceptTcpClient() nur diese Form.
Wie ich oben schon gesagt habe, beinhaltet das IAsyncResult
state die TcpListener-Instanz, die wir in der
StartAsyncAccepting()-Methode benutzt haben. Jetzt müssen wir nur einen weiteren TcpListener definieren und die Instanz per Typecast übergeben.
In der zweiten Zeile dieser Methode wird eine neue TcpClient-Instanz erzeugt, welche mittels
EndAcceptTcpClient() initialisiert wird.
Die
EndAcceptTcpClient(state)-Methode nimmt dann die ausstehnde Verbindung an.
Wichtig: der TcpListener darf erst jetzt gestoppt werden und nicht in
StartAsyncAccepting oder vor
EndAcceptTcpClient().
Und da alles in dem Hintergrundthread läuft (auch die
Callback-Methode) blockiert unsere Form nicht und das Programm läuft ungestört weiter.
Ich hoffe das Tutorial ist hilfreich.
TcpClient folgt wenn ich ausgeschlafen bin
.
Rechtschreibfehler sind geistiges Eigentum, aber ich beanspruche keine Urheberrechte daran
.
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler