Multi-Client mit TCPListener und TCPClient

tomecdark

Mitglied
Hallo Profis..
Ich versuche ein Programm zu schreiben, mit dem ich Virtuelle-Gelbe-Zettel durch Netzwerk / Internet verschicken kann.
Das ganze benötigt einen Server und mehrere Clients ( wenn es mal , so ca 25 )
Mein derzeitiges Problem ist, das die TCPListener Funktion anscheinend nur ein Client zur Zeit bearbeiten kann.

Da ich kein Profi bin, stelle ich mir das leihenhaft so vor:

Client 1 sendet Nachricht -> Server empfängt -> Server Prüft, ob empfänger Client Online ist -> Server sendet Nachricht ggf. zum EmpfängerClient oder speicher sie, bis er Online ist -> Sollte wären der Übertragung des ersten Clients ein 2ter eine Nachricht verschicken, soll der Server diese annhemen und abbarbeiten, wenn er fertig ist.

Bei mir läuft der TCPListener in einer Schleife und nimmt demnach auch alles an, was er kriegen kann und wirft eine MessageBox aus. Erst wenn ich diese mit OK bestätige wird der nächste Client angenommen. Vorher verschwindet die Übertragung des 2ten Client im Nirvana... Meine Idee wäre es zum Test, das er für jeden Client diese MessageBox auswirft..

Ich bin für jede Art von Tips dankbar!

Gruß

Tomec
 
Hi tomecdark!

Bevor ich weiter darauf eingehe möcht ich, dass Du dir erstmal diesen Thread durchliest:
[thread=179619][Remoting] Überprüfen, ob Server noch läuft - Thread[/thread]
Darin solltest erstmal einen kleinen abstrakten Aufbau des ganzen herraus lesen können.
Des Weiteren gibt es noch diesen Thread, mit noch ein paar mehr nützlichen Infos.
[thread=237446]C# - TcpListener/-Client Frage ... - Thread[/thread] (Durchklicken ;))

Frag einfach, sofern Du dann noch Fragen oder was nicht Verstanden hast. :)

MfG,
cosmo
 
ooouuuuu...
Ich Idiot... das wichtigste haben ich vergessen..

Ich arbeite mit VB.net.

Sorry cosmochaosmaker... Deine Beiträge hatte ich schon mit der Such-Funktion gefunden, aber konnte es dort schon nicht richtig mit meinen Fähigkeiten "konvertieren".

Trotzdem Danke für die schnell Antwort

Gruß

Tomec
 
Ich würde sagen eine MessageBox zu verwenden ist ziemlich unsinnig.
Bau doch in deinen Server ein Log ein,
welches Du auf deinem ServerForm ausgibst oder gar zusätzlich protokollierst.
Kannst die Verbindungsereignisse auch rudimentär in die Trace schreiben, wie Du halt willst.

C# sollte keine hürde darstellen. Immerhin hast die Objekte & Methodennamen
die Du dir abgucken kannst...
 
klar, messagebox ist nicht doll, aber dient ja auch nur zu testzwecken, ob überhaubt was ankommt. leider habe ich es nicht einmal hinbekommen, einen eintrag in eine ListBox zu generieren, weil die ausserhalb des Threads liegt!? ( Fehlermeldung von VB )

Mir ist auch klar, das mein vorhaben deutlich meinen Horizont übersteigen, aber mit Code-Beispielen bekomme ich das sicher hin.

Danke
 
tomecdark hat gesagt.:
klar, messagebox ist nicht doll, aber dient ja auch nur zu testzwecken, ob überhaubt was ankommt. leider habe ich es nicht einmal hinbekommen, einen eintrag in eine ListBox zu generieren, weil die ausserhalb des Threads liegt!? ( Fehlermeldung von VB )
Man kann nicht einfach so auf Controls zugreifen,
die in einen anderem Thread erstellt wurden. Ich schätze mal Du fängst grad erst
mit der Visuellen Programmierung an?
[thread=194642]Thread übergreifender Control-Zugriff - Thread[/thread]

Abstrahiere deine Umgebung (Teile die Aufgabenbereiche in Klassen auf).
Definiere Events für deine ServerKlasse,
die Du auf dem Form, welche Sie dann aboniert, invokst.
[thread=219770]... wird im falschen Thread ausgeführt - Thread[/thread]

tomecdark hat gesagt.:
Mir ist auch klar, das mein vorhaben deutlich meinen Horizont übersteigen, aber mit Code-Beispielen bekomme ich das sicher hin.
Ein abstrakter Aufbau des Ganzen hilft ungemein,
einen klaren Aufbau zu schaffen und die Übersicht zu behalten.
Alles hingegen zu vermischen, erschwert den klaren Überblick.
Zudem lässt sich dann auch leichter erkennen, was in welchem Thread ausgeführt werden soll.
[thread=219309]Threadhandling .Suspend() <-> .Abort()[/thread]

Ohne OOP wirst hier sicher schnell an die Grenzen des Möglichen stoßen.
Sicher bekommt man es auch ohne hin. Viele PHP'ler machen es einen "gekonnt" vor... :D
Das erzeugt aber Code, der nur der Entwickler selber versteht, nicht aber ein Kollege.
Hoffe Du verstehst meine Intension in dem Zusammenhang.

Du, mein erstes richtiges Programm war Schiffe Versenken auf der Console.
OOP gerecht implemetiert, damit ich das als erstes lerne. ;)
Mein zweites war ein TCP Server für dieses Spiel, um es übers Netzwerk Spielen zu können.
Auch OOP gerecht implemetiert, damit es für mich überhaupt noch überschaubar war...

MfG,
cosmo
 
Zuletzt bearbeitet:
Jetzt, wo ich richtig Kopfschmerzen habe ;-) muß ich sagen, das mir das Thema doch noch zu hoch ist.
Ich bin leider nicht in der Lage die C# Codes zu "übersetzten". Um es besser verstehen zu können, werde ich vb.net 2.0 Codes benötigen.

Trotzdem Vielen Dank für die Hilfe Cosmo!
 
Nun habe ich noch etwas mehr probiert und habe nun meinen Code als PDF angehängt.
Das ganze sieht noch leer aus und ist auch erst mal nur zum Test gedacht.

Mir würde es helfen, wenn ich den Backgroundworker optimiert bekäme und ich den Zugrif auf ListBox_Log hinbekomme. Er trägt den ersten Connect eines Clients ein, bei jedem weiteren sagt er, das er auf das Objekt nicht zugreifen könne, weil es aus einem anderen Thread kommt ( oder so änlich.. )
Es wurden schon viele Beiträge zum Thema gepostet, aber wie ich schon in meinen anderen Posts sagte, bekomme ich das nicht übersetzt.

Freue mich über jeden Denkanstoß

Gruß Tomec
 

Anhänge

  • 24816attachment.pdf
    15,9 KB · Aufrufe: 746
Hi Tomec!

WTF? Warum postest das jetzt als PDF? :D
Poste doch gleich eine Demo, sodass jeder der Lust hat seine Verbesserungen reinhacken kann. ;)
Oder Du verwendest die CodeTags: [post=1225555]Tagebuch zur tutorials.de v.6 - Entwicklung - 1. Post[/post]

Du kannst wie gesagt nicht auf Objekte zugreifen die in einem anderen Thread erstellt wurden.
Dafür musst den Vorgang auf dem Thread invoken der das Objekt erstellt hat.
Ich hatte mich wohl etwas zu fachlich ausgedrückt, sry. :)

Hab sogar einen Thread gefunden der dir ein Beispiel in VB aufzeigt:
[thread=243609]Threadübergreifung - Thread[/thread]

MfG,
cosmo
 
cosmochaosmaker hat gesagt.:
...Poste doch gleich eine Demo, sodass jeder der Lust hat seine Verbesserungen reinhacken kann. ;)...

Code:
Imports System.Net
Imports System.Net.Sockets

Public Class Form_Programm

    Dim ServerStatus As Integer = 0 '0=Offline 1=Online 2=Besetzt 3=AdminModus

    'Programmstart:
    Private Sub Form_Programm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If ServerStatus = 0 Then
            Button_Server.Text = "Server starten"
        Else
            Button_Server.Text = "Server anhalten"
        End If
        Call ServerOffline()
    End Sub

    'Buttons:
    Private Sub Button_Server_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Server.Click
        If ServerStatus = 0 Then
            Call ServerOnline()
        Else
            Call ServerOffline()
        End If
    End Sub
    Private Sub Button_LogLoeschen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_LogLoeschen.Click
        ListBox_Log.Items.Clear()
    End Sub

    'Funktionen:
    Private Sub ServerOnline()
        ServerStatus = 1
        ToolStripStatusLabel_ServerStatus.Text = "Online"
        ToolStripStatusLabel_ServerStatus.ForeColor = Color.Green
        Button_Server.Text = "Server anhalten"
        BackgroundWorker_TcpListener.RunWorkerAsync()
    End Sub

    Private Sub ServerOffline()
        ServerStatus = 0
        ToolStripStatusLabel_ServerStatus.Text = "Offline"
        ToolStripStatusLabel_ServerStatus.ForeColor = Color.Red
        Button_Server.Text = "Server starten"
        BackgroundWorker_TcpListener.CancelAsync()
    End Sub

    'BackgroundWorker:
    Private Sub BackgroundWorker_TcpListener_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker_TcpListener.DoWork
        Dim ipAdresse As IPAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList(0)
        Dim Port As Int32 = 12345
        Dim Server As New TcpListener(ipAdresse, Port)
        Server.Start()
        Do While ServerStatus = 1
            Dim Sitzung As Socket = Server.AcceptSocket
            ListBox_Log.Items.Add(Date.Now & " - Verbindung hergestellt")
            Sitzung.Close()
        Loop
        Server.Stop()
    End Sub
End Class

LOL...Und Ich frag mich immer, wie ihr das gemacht habt..

Vielleicht findet ja jemand den Fehler... ( wenn es überhaupt was richtiges gibt ;-) )
 
Zurück