Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
TCPListener und die Endlosschleife
Der Zaehe
myCSharp.de - Member



Dabei seit:
Beiträge: 35

Themenstarter:

TCPListener und die Endlosschleife

beantworten | zitieren | melden

Hallo!

Ich habe angefangen, mir mit Hilfe der MSDN die Verwendung des TcpListener beizubringen und habe nun eine ganz entscheidende Frage: Wie soll ich die Endlosschleife vermeiden, die meine ganze Anwendung blockiert? Ein Vorschlag für die Realisierung eines Multi-Thread-Servers, der mehrere Clients gleichzeitig bearbeiten kann, sieht so aus:


public class ClientHandler 
{

    private TcpClient client;
    private string ID;

    public ClientHandler(TcpClient client, string ID) 
    {

        this.client = client;
        this.ID = ID;
    }

    public void Start() 
    {

        // Den Netzwerk-Stream abrufen.
        NetworkStream stream = client.GetStream();

        // Einen BinaryWriter erstellen, um in den Stream zu schreiben.
        BinaryWriter w = new BinaryWriter(stream);

        // Einen BinaryReader erstellen, um aus dem Stream zu lesen.
        BinaryReader r = new BinaryReader(stream);

        if (r.ReadString() == ClientMessages.RequestConnect) 
        {

            w.Write(ServerMessages.AcknowledgeOK);
            Console.WriteLine(ID + ": Verbindung beendet.");
            while (r.ReadString() != ClientMessages.Disconnect) {}

            Console.WriteLine(ID + ": Verbindungstrennungsanforderung empfangen.");
            w.Write(ServerMessages.Disconnect);
        }
        else 
        {
            Console.WriteLine(ID + ": Verbindung konnte nicht beendet werden.");
        }

        // Den Verbindungs-Socket schließen.
        client.Close();
        Console.WriteLine(ID + ": Verbindung geschlossen.");

        Console.ReadLine();
    }
}

public class TcpServerTest
{
    private static void Main()
    {
        // Erstellen eines neuen Listeners (Abhörer) an Anschluss 8000.
        TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 
            8000); 
        
        Console.WriteLine("Server: Initialisiere Anschluss.");
        listener.Start();
        Console.WriteLine("Server: Warte auf eingehende Verbindungsanforderungen...");
        
        int clientNum = 0;
        while (true)
        {
            try 
            {
                // Auf eingehende Verbindungsanforderung warten 
                // und einen für die Kommunikation initalisierten TcpClient zurückgeben. 

                TcpClient client = listener.AcceptTcpClient();
                Console.WriteLine("Server: Verbindung akzeptiert.");

                // Ein neues Objekt erstellen, um diese Verbindung zu bearbeiten.
                clientNum++;
                ClientHandler handler = new ClientHandler(client, "Client " +
                    clientNum.ToString());

                // Dieses Objekt in einem anderen Thread ausführen.
                Thread handlerThread = 
                    new Thread(new ThreadStart(handler.Start));
                handlerThread.IsBackground = true;
                handlerThread.Start();

                // (Sie könnten Handler und HandlerThread auch zu einer Auflistung hinzufügen,
                // um die Client-Sitzungen zu überwachen.)
            }
            catch (Exception err) 
            {
                Console.WriteLine(err.ToString());
            }
        }
    }
}

Da ich den Code leicht verändert in einem Form ausführe, nicht in der Konsole, und das Form noch "bedienbar" sein sollte, müsste ich doch auch noch die Endlosschleife zum Annehmen der Verbindungen in einen speraten Thread tun, oder?

Ich bin von Delphi zu C# "umgesiedelt", da ich gemerkt habe, dass die Sprache einfach viel mehr Möglichkeiten bietet, aber vermisse nun auch die etwas sehr viel leichter zu bedienenden TServerSocket- und TClientSocket-Komponenten, die eine Ebene höher angelegt waren, als es TcpClient und TcpListener sind.

Schon mal Danke für eure Tips!

mfg
Der Zaehe
private Nachricht | Beiträge des Benutzers
Big Al
myCSharp.de - Member



Dabei seit:
Beiträge: 348
Herkunft: Mannheim

beantworten | zitieren | melden

Hi,
warum nimmst du nicht die Methode von Programmierhans:
Multi-TcpClient
Ich hab den Code mal in einer WinForms Anwendung benutzt und alles
hat gefunzt.
Viele Grüße,
Big Al
Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.
private Nachricht | Beiträge des Benutzers
Der Zaehe
myCSharp.de - Member



Dabei seit:
Beiträge: 35

Themenstarter:

beantworten | zitieren | melden

Danke, genau so etwas habe ich gesucht! =)

Da tut sich noch eine neue Frage auf:
In der Schleife ist ja eine Pause von 100 ms vorgesehen, falls nichts verarbeitet werden muss. Das bedeutet aber auch, das eingehende Daten mit einer maximalen Verzögerung von 100 ms verarbeitet werden. Wie wird dieses Problem in Spielen gelöst, wo bekanntlich ein sehr hoher Ping anzustreben ist?
private Nachricht | Beiträge des Benutzers
Franknstein
myCSharp.de - Member



Dabei seit:
Beiträge: 531

beantworten | zitieren | melden

Ich habe noch nie ein Spiel programmiert, aber Spiele haben eh immer eine Endlosschleife, in welcher alle Aktionen abgearbeitet werden. Daher ist es auch kein Problem, da auch noch einen Socket abzufragen, ob neue Daten da sind... Und da ein Spiel eigentlich das selbe Verhalten wie eine Endlosschleife hat, welche nirgends pausiert, braucht man auch nirgends das Programm schlafen zu lassen.
Besuchen sie das VisualC++ - Forum
private Nachricht | Beiträge des Benutzers
Big Al
myCSharp.de - Member



Dabei seit:
Beiträge: 348
Herkunft: Mannheim

beantworten | zitieren | melden

Da bin ich aber anderer Meinung!
Wenn du dein Programm in einer Endlosschleife laufen lässt
steigt die Prozessoraktivität auf 99%, und das is ja wohl auf
'nem normale PC nicht gut.
Wenn der nur als Server läuft vielleicht, aber sonst???
Big Al
//edit: Hat sich erledigt, hab übersehen, dass du nur von Spielen redest
Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.
private Nachricht | Beiträge des Benutzers