Start / Tutorials / Winsock Programmierung
 
Startseite Up-/Download Tutorials Club Das Team
Rubriken Foren Bücher Tips 'n Tricks Suche


Winsock Programmierung


  Einleitung

In der letzten Folge habe ich gezeigt, wie Du mit dem Winsock-Control einen einfachen Chat programmieren kannst. In dieser Folge gehe ich ein wenig weiter. Dieses mal ist ein Chat an der Reihe, in dem mehrere Personen zusammen chatten können.

Wenn Du den vorigen Artikel nicht gelesen hast, würde ich das empfehlen.

Mit freundlichen Grüßen
Patrice Neff

Inhalt

Vorwort
Der Nachrichtenaufbau
Nachrichten durch die Leitungen senden
Nachrichten an die Clients senden
Die Methode Listen
Die Kontaktaufnahme
Kaum verändert: Der Client
Nachrichten senden
Daten empfangen
Beispiel als Download

  Vorwort

Bei dem Chat, den ich hier vorstelle, ist ein Chat-Server nötig. Dessen IP muss jedem Chatter bekannt sein. Danach können alle Benutzer zu diesem Server verbinden, um miteinander zu chatten. Der Server muss also die verschiedenen Benutzer verwalten. Nun kann aber mit dem Winsock-Control nur eine Verbindung geöffnet werden. Wie ist es denn möglich, mehrere Benutzer auf den Server zu lassen? Die Antwort ist einfach: Mit Hilfe eines Steuerelementfeldes (Array). Zur Laufzeit werden dynamisch Winsock-Controls hinzugeladen. Mit jedem geladenen Control kann genau eine Verbindung geöffnet sein. Aber der Reihe nach...

  Der Nachrichtenaufbau

Bei unserem ersten Beispiel war der Aufbau der Nachrichten so einfach wie es nur geht. Erst 50 Zeichen für den Namen und dahinter kam die Nachricht. Das reicht für dieses Beispiel nicht mehr. Denn jetzt identifizieren sich die Clients bei dem Server. Deshalb wird das erste Zeichen der Datei dazu verwendet, den Nachrichten-Typ zu kennzeichnen. Wenn dieses erste Zeichen eine Null ist, handelt es sich um eine Nachricht eines Benutzers. (z.B. "Hallo Hansi") Steht jedoch eine Eins am Anfang, so handelt es sich um eine Identifikation. Bei dieser werden 51 Zeichen übermittelt. (Die Eins und der Name des Benutzers)

  Nachrichten durch die Leitungen senden

Das Versenden von Nachrichten übernimmt wieder die Prozedur Senden, an der wir jedoch leichte Änderungen vornehmen müssen, da die Winsock-Controls neu mit einem Index versehen sind. Sehen wir uns die Sub mal an:

Sub Senden(strData As String, Optional Index As Integer = 0)
    blnSendCompleted = False
    If wsckChat(Index).State = sckConnected Then
        wsckChat(Index).SendData strData
        Do Until blnSendComplted
            DoEvents
        Loop
    End If
End Sub

Erklärungen: Geändert hat sich, dass neu ein Parameter Index übergeben wird. Dieser ist jedoch optional, muss also nicht zwingend Angegeben werden, wodurch die Sub abwärtskompatibel wird. Standardmässig wird der Index 0 verwendet.

  Nachrichten an die Clients senden

Ein Client kann nur an den Server senden, nicht aber an den Benutzer direkt. Deshalb muss der Server die reinkommenden Nachrichten an alle Clients weiterleiten. Dies geschieht mit der folgenden Methode ForwardMsg.

Sub ForwardMsg(strData As String, intExcludeIndex As Integer)
Dim intCounter As Integer
    If wsckChat.Count > 1 Then
        For intCounter = 1 To wsckChat.Count - 1
            If intCounter <> intExcludeIndex Then
            Senden strData, intCounter
            End If
        Next
    End If
End Sub

Erklärungen: Diese Funktion durchläuft alle geladenen Winsock-Controls. Für jedes Control wird geprüft, ob eine Verbindung offen ist. Ist dies der Fall, ruft das Programm die Funktion Senden auf, um die Nachricht zu verschicken.

  Die Methode Listen

Auch in diesem Beispiel verwenden wir wieder die Methode Liste, die wir bereits im erste Teil verwendet haben. (Wenn dir das nichts sagt, dann ab zum ersten Teil ;-)

Sub cmdListen_Click()
    strNick = Left(txtName & Space(50), 50)
    blnServer = True
    wsckChat(0).LocalPort = 12123
    wsckChat(0).Listen
End Sub

Erklärungen: Der Code sieht wieder sehr ähnlich aus. Da aber unser Winsock-Control jetzt ein Array ist, müssen wir einen Index verwenden. Das Haupt-Control, welches wir für Listen verwenden, hat den Index 0. Ausserdem kommt die Variable blnServer hinzu. Diese ist für das ganze Formular gültig und gibt an, ob die aktuelle Programm-Instanz ein Server oder ein Client ist.

  Die Kontaktaufnahme

Auch hier wird wieder das Event ConnectionRequest gefeuert, sobald ein Client Kontakt aufnimmt. Aber wir können jetzt nicht den Code verwenden, den wir noch im ersten Beispiel verwendet haben. Der Grund ist, dass wir das Control mit dem Index Null nicht schliessen dürfen. Schliesslich muss dieses die Verbindungsversuche für die kommenden Benutzer beantworten. Deshalb wird hier ein zusätzliches Winsock-Control hinzugeladen.

Sub wsckChat_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    wsckChat(GetNextFreeIndex).Accept requestID
End Sub

Erklärungen: Komisch, nicht. Wieso wird hier nur eine Zeile benötigt? Das Geheimnis liegt in der Funktion GetNextFreeIndex!

Function GetNextFreeIndex() As Integer
    Dim intCounter As Integer
    For intCounter = 1 To wsckChat.Count - 1
        If wsckChat(intCounter).State = sckClosed Then
            GetNextFreeIndex = intCounter
            Exit Function
        End If
    Next
    GetNextFreeIndex = wsckChat.Count
    Load wsckChat(GetNextFreeIndex)
End Function

Erklärungen: Diese Funktion ist doch ein bisschen grösser. Die Aufgabe der Funktion ist, den Index des ersten geschlossenen Winsock-Controls (State = sckClosed) zurückzugeben. Wenn kein geschlossenes Control gefunden wird, sorgt die Funktion auch gleich für Nachschub und lädt ein zusätzliches Control.

  Kaum verändert: Der Client

Sub cmdConnect_Click()
Dim strRemoteComputer As String
    strNick = Left(txtName & Space(50), 50)
    strRemoteComputer = InputBox("RemoteHost:")
    If Trim(strRemoteComputer) = "" Then Exit Sub
    blnServer = False
    wsckChat(0).RemotePort = 12123
    wsckChat(0).RemoteHost = strRemoteComputer
    wsckChat(0).Connect
End Sub

Erklärungen: Wir Du siehst, ändert sich an dem Code so gut wie nichts. Die einzige Änderung ist, dass jetzt über einen Index auf das Winsock-Control zugegriffen werden muss. Der Client greift immer über das Control mit dem Index 0 auf den Server zu. Auch hier kommt noch die Variable blnServer dazu.

Ausserdem kommt noch folgender Code hinzu:

Sub wsckChat_Connect(Index As Integer)
    If blnServer = False Then
        Senden "1" & strNick
    End If
End Sub

Erklärung: Mit diesem Code erreichen wir, dass sich ein Client beim Server identifiziert. wsckChat_Connect wird aufgerufen, sobald der Server die Methode Accept aufruft.

  Nachrichten senden

Bereits jetzt können sich verschiedene Benutzer auf dem Server einloggen. Jetzt folgt noch die Möglichkeit, dass die Benutzer Nachrichten senden könen. Die dazu nötigen Methoden Senden und ForwardMsg haben wir ja bereits implementiert.

Das wichtigste ist, dass wir beim Senden unterscheiden müssen, ob die aktuelle Instanz als Server oder als Client läuft. Denn läuft sie als Server, muss die eingegebene Nachricht an alle verbundenen Benutzer gesendet werden. Der Client sendet die Nachricht an den Server.

Sub cmdSend_Click()
Dim strMessage As String
    strMessage = "0" & strNick & txtNachricht.Text
    If blnServer Then
        ForwardMsg strMessage, 0
    Else
        Senden strMessage, 0
    End If
    AddMessage txtNachricht.Text, strNick
End Sub

Erklärungen: Als erstes wird der String zusammengebaut, welcher über das Netzwerk versendet wird. Dieser besteht aus einer führenden 0, da es sich um eine normale Nachricht handelt. Danach kommt der Nick und anschliessend der eingegebene Text. Dann unterscheidet das Programm zwischen Server/Client. Wenn die Instanz als Server läuft, wird die Nachricht an alle verbundenen Clients weitergeleitet. Bei einem Client wird die Nachricht an den Server geschickt.

  Daten empfangen

Nun folgt ein sehr wichtiger Teil: Die ankommenden Daten müssen verarbeitet werden. Auch hier haben Server und Client unterschiedliche Aufgaben. Der Server muss Nachrichten an alle Clients weiterleiten. Ausserdem muss er dafür sorgen, dass sich die Clients anmelden können.

Sub wsckChat_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim strData As String, strNick As String, strMessage As String
    wsckChat(Index).GetData    strData
    If Left(strData, 1) = "0" Then
        strNick = Trim(Mid(strData, 2, 50))
        strMessage = Mid(strData, 52)
        AddMessage strMessage, strNick
        If blnServer Then ForwardMsg strData, Index
    ElseIf Left(strData, 1) = "1" Then
        strNick = Trim(Mid(strData, 2, 50))
            If blnServer Then
                wsckChat(Index).Tag = strNick
                ForwardMsg Left("-system-" & Space(50), 50) & "1" & strNick, Index
            End If
        AddMessage "Der User " & strNick & " betritt den Chat.", "-system-"
    End If
End Sub

Erklärungen: Nach dem Einlesen der einkommenden Daten wird das erste Zeichen der Daten geprüft. Handelt es sich dabei um eine Null, so kommt eine normale Nachricht herein, welche ausgegeben und evtl. an die Clients weitergeleitet werden muss. Steht jedoch eine Eins an erster Stelle, loggt sich ein Client ein. Dann wird eine Nachricht ausgeben, dass ein neuer User den Chat betreten hat und die Clients werden informiert.

  Beispiel als Download

Endlich am Ende! ;-) Wie Du siehst, ist die Programmierung eines Chats, der mehrere Benutzer zulassen soll, bereits ein wenig komplexer. Doch viele Ideen habe ich hier noch nicht eingebaut. Ein paar Ideen, damit Du Dein Wissen nun ein wenig festigen kannst: Alle User auflisten, private Nachrichten, mehrere Channels, etc. Sei einfach kreativ ;-)

Original des Tutorials auf http://www.patrice.ch/de/computer/programming/visualbasic/tips/winsock2

Beispielprojekt

Ihre Meinung

Falls Sie Fragen zu oder Erfahrungen mit diesem Tutorial haben, dann sollten Sie diese hier posten. Für alles weitere melden Sie sich bitte in einem zum Thema passendem Forum.

Falls Sie in ihren Kommentar Sourcecode einbinden wollen, verwenden Sie bitte Pseudotags: Sourcecode für VB5/VB6 wird durch ein vorangestelltes [code] markiert und durch [/code] abgeschlossen. Bei VB .NET verwendet man [dotnet] und [/dotnet].

Ihr Name:   
Ihre E-Mailadresse:   
 
Bitte folgende Kontrollnummer eingeben: 405
Kontrolle:   
Ihre Frage/Ihr Kommentar:
Ja, ich möchte weitere Beiträge per E-Mail erhalten
Von Jan am 06.06.2007 um 18:14
@NightstarX,
vielleicht hat er nicht die Vollversion, sondern nur eine Einsteiger. Dann kann er nämlich das Winsock gar nicht nutzen und eine Fehlermeldung erscheint.
Von Nightstarx am 05.06.2007 um 17:16
mmm also schlecht ist das nicht auch leicht zu machen nur giebt es da ein problem wen ich das fertige project dan mein kolege schicke kan er es dan nicht öffnen oder ausführen da den immer eine fehlermeldung kommt
was ich den doch sehr komisch finde den bei mir geht alles
naja aber nicht schlecht
Von jan am 26.04.2007 um 12:39
@Maddin
Die Meldung "Connection forsly rejekted" erscheint sobald der Server den Port noch nicht geöffnet hat. Erst öffnen (sckWinsock.listen) dann connecten (sckWinsock.connect ...)

Von jan am 26.04.2007 um 12:39
@Maddin
Die Meldung "Connection forsly rejekted" erscheint sobald der Server den Port noch nicht geöffnet hat. Erst öffnen (sckWinsock.listen) dann connecten (sckWinsock.connect ...)

Von Denise am 06.12.2006 um 17:31
Bitte Bitte helft mir... ich barauche umbedingt ein JAVA Programm... (SPAREN) wenn ihr das habt bitte bitte schickt es...
Von Maddin am 28.07.2006 um 11:20
Ich krieg imma Connection forsly rejekted (oder so ähnlich). wenn ich über localhost(127.0.0.1) connecte. Was kann ich da tun? Ports sind gleich, aber der nimmt den Port irg nit Oo
Von Maddin am 27.07.2006 um 00:14
Toll und wie mach ich jez nen Server? Ich wollte eig nen eig chat haben also client und server, aber das geht bei mia irg net :(
Von Gast am 06.02.2006 um 14:21
@Ronald
Dim ars As String
ars = "0" & strnick & " connected"
fowardmsg ars, 0

^^ probier mal den sollte gehen
Von ww1com "joerg" am 25.11.2005 um 01:44
Hallo alle zusammen.

Chat server leuft.

Folgende Frage .



1.
wie kann ich html code schreiben das ich peer html auch denn chat server connecten kann und tippern kann

wehre dankbar wenn ich eine antwort bekomme.
Von Marc am 01.11.2005 um 20:09
Hallo zusammen,

habe mal ne Frage.
Habe alles so gut verstanden nur ich brauche ja auch ein Programm wo ich den Chat hinmachen kann. Kenne aber keins, könnt ihr mir helfen?
Danke
Von w1z4rd am 15.08.2005 um 13:27
Hallo zusammen. Habe ein Problem :(
Wenn ich auf einem PC ein listen mache und mit einem anderen drauf connecte und nachrichten schreibe sehe ich nur meine nachrichten.
Was muss ich machen damit ich alle nachrichten von allen clients sehe????

Gruss
Von Christoph B. am 22.05.2005 um 14:50
Geiles Programm!
Hut ab vor deinem Code!
Von Ronnie am 19.04.2005 um 19:29
Hat sich erledigt. Port-Forwarding im Router war aus :-))
Naja, die kleinen dinge des lebens *g*
Von Ronnie am 19.04.2005 um 18:31
Soweit, sogut. Aber wie connecte ich den Server jetzt übers Internet?? Mit der Externen IP funzt das bei mir nicht??
Von sandra schönfeld am 25.03.2005 um 21:54
ich möchte einen chat programmieren bin auf diesem gebiet aber total unerfahren es sollte ein chat sein in dem ein user sich nur mit einem nick anmelden kann und ein administor im bedarfsfall jemanden des chats verweisen kann mit animierten smileys den chat bunt gestalten kann danke für ihre hilfe
Von Ronald am 21.03.2005 um 00:49
Hallo,
dieser Code kann nicht richtig funktionieren. Ich habe ewig gesucht und gekämpft und gedebuggt, bis ich den Fehler gefunden habe. Kurze Beschreibung vorher. Ein Client (nennen wir ihn ClientX) meldet sich beim Server an. Also erscheint im Chattextfenster vom Server die Meldung, daß ClientX den Raum betreten hat.
ElseIf Left(strData, 1) = "1" Then
strNick = Trim(Mid(strData, 2, 50))
If blnServer Then
wsckChat(Index).Tag = strNick
ForwardMsg Left("-system-" & Space(50), 50) & "1" & strNick, Index
End If
AddMessage "Der User " & strNick & " betritt den Chat.", "-system-"
End If

Da aber hier bei diesem Beispiel der zu übermittelnde String mit "-system-" beginnt, werden bei den anderen Clients nie Meldungen erscheinen können, daß andere User den Raum betreten haben. Einfach aus dem Grund, weil das erste Zeichen beim "Data_Arrival" überprüft wird, und zwar auf 0 oder 1 und nicht auf "-system-".

Eine Frage habe ich noch: Was macht eigentlich dieses Stück Code, also "Left("-system-" & Space(50), 50) & "1" & strNick, Index" ?? Oder anders gefragt, was bewirkt die LEFT-Funktion??

Ich hoffe, auf baldige Hilfe.
Gruß Ronald



Aber die anderen Clients, die schon da sind, also ClintY und ClientZ als Beispiel, wollen doch auch wissen, wer sich zu ihnen gesellt hat.
Von Gamenet Programmierung am 18.09.2004 um 15:06
Das funktioniert bei mir irgendwie nicht, ich möchte mich mit dem chatcity.de server verbinden (Chatcity= www.chatcity.de (Chat) ) Das funktioniert aber nicht, ich kann die nachrichten der anderen nicht sehen!
Von Lukas am 20.08.2004 um 17:26
Wia kann ich Clients kickn??

Danke
Von Martin am 21.12.2003 um 23:41
Halo,
klar im Eigenschaftenfenster...;).., aber bei mir gibt es diese Eigenschaft "Index von Winsock" nicht.
Ich habe alle Eigenschaften im Control ausser diese mit "Index"...man muss sie erst hinzufügen, und da weiss ich nett wie's geht.

Aber trotzdem vielen Dank "VB" ;)

mfg
Martin
Von VB am 20.12.2003 um 22:46
Also martin ich kenn mich in vb.net nich so gut aus! aber in vb 6 is es so das man z.b. man kann den index im eigenschaftsfenster ganz einfach anklicken aber vb.net sry...!
Von Martin am 18.12.2003 um 19:59
Hallo, muss einen Chat Programmieren und bin neu in VB.Net und ASP.NET eingestigen.
Komme mit dem (Index 0) und der WinsockArray.dll nicht klar...

Wie, Wo setze ich den Index von Winsock auf 0, so dass auch bei mir in den "Eigenschaften" von Winsock (Index von Winsock) steht?
Bei mir gibt es alle ausser diese Einstellung!
Muss man die selbst hinzufügen ?
Wie erstelle ich so ein WinsockArray.dll?

Wär echt super nett wenn jemand mir da helfen könnte, bin schon am verzweifeln.

(Benutze Visual Studio.NET 2003)

mfg Martin
Von Martin am 18.12.2003 um 19:49
Hallo, muss einen Chat Programmieren und bin neu in VB.Net und ASP.NET eingestigen.
Komme mit dem (Index 0) und der Array.dll nicht klar...

Wie, Wo setze ich den Index von Winsock auf 0, so dass auch bei mir in den "Eigenschaften" von Winsock (Index von Winsock) steht?
Wie erstelle ich so ein Array.dll?

Wär echt super nett wenn Du mir da helfen könntest, bin schon am verzweifeln.

(Benutze Visual Studio.NET 2003)

mfg Martin

Erstellt: 06.02.2003
Aktualisierung: 06.02.2003
  Autor: Patrice Neff
E-Mail: Tutorials@ActiveVB.de



Copyright © 1998-2010 by ActiveVB
Alle Rechte vorbehalten.