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
[GELÖST] Server schließt sich immer nach getrennter Verbindung
KevinHappy
myCSharp.de - Member



Dabei seit:
Beiträge: 41

Themenstarter:

[GELÖST] Server schließt sich immer nach getrennter Verbindung

beantworten | zitieren | melden

Hallo,

ich habe mir das Tutorial "Client-/Server-Komponente über TCP-Sockets" hier auf der Seite gerade angeschaut und wollte diesen Code für mich Optimieren.

Bissher habe ich diesem Code:


    /// <summary>
    /// Zusammenfassung für den Server
    /// </summary>
    public class Server
    {
        /// <summary>
        /// Port, auf dem der Server auf Clientverbindungen wartet
        /// </summary>
        public const int serverListenPort = 10000;

        /// <summary>
        /// Anzahl Millisekunden in Warteschleifen
        /// </summary>
        public const int sleepTime = 200;

        /// <summary>
        /// Der Haupt-Thread
        /// </summary>
        private Thread mainThread;

        /// <summary>
        /// IP-Adresse, an der auf Verbindungen gewartet werden soll.
        /// Standardmässig wird auf allen Schnittstellen gewartet.
        /// </summary>
        public IPAddress ipAddress = IPAddress.Any;

        /// <summary>
        /// Der Standardkonstruktor richtet den Thread ein, welcher
        /// anschliessend auf Client-Verbindungen wartet.
        /// </summary>
        public Server()
        {
            // Hauptthread wird instanziiert ...
            mainThread = new Thread(new ThreadStart(this.mainListener));
            // ... und gestartet
            mainThread.Start();
        }

        /// <summary>
        /// Haupt-Thread, wartet auf neue Client-Verbindungen
        /// </summary>
        private void mainListener()
        {
            // Alle Netzwerk-Schnittstellen abhören
            TcpListener listener = new TcpListener(ipAddress, serverListenPort);
            System.Console.WriteLine("Listening on port " + serverListenPort + "...");
            try
            {
                // Verbindungsannahme aktivieren
                listener.Start();
                // Warten auf Verbindung
                while (!listener.Pending()) { Thread.Sleep(sleepTime); }
                // Verbindung annehmen
                Socket newSocket = listener.AcceptSocket();
                // Mitteilung bzgl. neuer Clientverbindung
                System.Console.WriteLine("Neue Client-Verbindung (" +
                            "IP: " + newSocket.RemoteEndPoint + ", " +
                            "Port " + ((IPEndPoint)newSocket.LocalEndPoint).Port.ToString() + ")");
            }
            catch (Exception ex)
            {
                throw new Exception("Fehler bei Verbindungserkennung", ex);
            }
        }
    }

Ich möchte nun aber den Server starten und dann soll er laufen, bis man ihn wieder manuell schließt. Quasi eine Endlosschleife. Zuerst möchte ich, dass das ganze mit einer Verbindung stabil funktioniert.

Wie bekomme ich das hin?

Edit:
Habe jetzt

for (; ; ){...}
genommen.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von KevinHappy am .
--
Vielen Dank

LG
Kevin
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16234

beantworten | zitieren | melden

Deine in den Startbeitrag hinein editierte Lösung ist nicht gerade sauber.
Ich sehe am Code Deines Servers auch nicht, wieso es nicht dauerhaft laufen sollte.
Vermutlich ist es ein Fehler, wie Du die Server-Klasse nutzt.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
KevinHappy
myCSharp.de - Member



Dabei seit:
Beiträge: 41

Themenstarter:

beantworten | zitieren | melden

Hi Abt,

ich erstelle einfach beim Programmstart ein Objekt von der Server Klasse.
Mehr passiert hier nicht. Wenn der Client geschlossen wird, schließt sich der Server.
--
Vielen Dank

LG
Kevin
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2361

beantworten | zitieren | melden

Das Grundproblem liegt aus meiner Sicht darin, dass du nur einen Client annimmst. Wenn der Client disconnected wird auch dein Thread verlassen. - Bisher dacht ich immer, dass das vorher schon passiert - Aber vielleicht ist es ja auch so.

Wie sieht denn deine Program.cs aus?
Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
KevinHappy
myCSharp.de - Member



Dabei seit:
Beiträge: 41

Themenstarter:

beantworten | zitieren | melden

So:

Das Sleep ist einfach nur drin, dass ich seh was in der Console steht, bevor der Server beendet wird.


    class Program
    {
        static void Main(string[] args)
        {
            Server srv = new Server();
            System.Threading.Thread.Sleep(10000);
        }
    }
--
Vielen Dank

LG
Kevin
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2361

beantworten | zitieren | melden

Schön wäre es, wenn du deine Lösung noch posten würdest.

// EDIT
Statt dem Thread.Sleep() solltest du eher Console.ReadLine() oder ähnliches verwenden. Dann bleibts auch stehen, wenn du mal abgelenkt bist. :)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von inflames2k am .
Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
KevinHappy
myCSharp.de - Member



Dabei seit:
Beiträge: 41

Themenstarter:

beantworten | zitieren | melden

Zitat von KevinHappy
Edit:
Habe jetzt

for (; ; ){...}
genommen.

Die Lösung steht schon im Startthread.
Das Sleep kommt auch wieder raus, war nur zu Testzwecken.
--
Vielen Dank

LG
Kevin
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2361

beantworten | zitieren | melden

Ich versteh die Lösung nicht. - Also denke ich, wird auch kein anderer wissen was du nun mit der For-Schleife anfängst.
Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
KevinHappy
myCSharp.de - Member



Dabei seit:
Beiträge: 41

Themenstarter:

beantworten | zitieren | melden

Die Lösung ist einfach eine Endlosschleife.


public void Process()
        {
            MySQL mysql = new MySQL();
            DateTime now = DateTime.Now;
            MemoryStream mem = new MemoryStream();// Empfangspuffer
            byte[] buffer = new byte[BufferSize];
            int TimeOut = 0;
            instanceOfClass.newMessage("Server gestartet");

            //while (TimeOut < (10 * 1000 / SleepTime))
            for (; ; )
            {
                //Console.WriteLine("1 - jhadbfhibsdb");
                mem.Seek(0, SeekOrigin.Begin);
                mem.SetLength(0);
                while (socket.Available > 0)
                {
                    //Console.WriteLine("2 - jhadbfhibsdb");
                    //Byte[] buffer = new byte[bytesAvailable];
                    int bytesRead = socket.Receive(buffer, buffer.Length, SocketFlags.None);
                    if (bytesRead ≤ 0) continue;
                    mem.Write(buffer, 0, bytesRead);
                    //instanceOfClass.Receive(buffer);
                    // Alles zurücksetzen
                }
                if (mem.Length > 0)
                {
                    //Console.WriteLine("3 - jhadbfhibsdb");


                    //if (System.Text.Encoding.ASCII.GetString(mem.ToArray(), 0, 4) == "quit")
                    //{
                    //    instanceOfClass.closeConnection();
                    //    //socket.Close();
                    //    Console.WriteLine("Client (" + socket.RemoteEndPoint + ") wurde vom Server getrennt.");
                    //}
                    if (System.Text.Encoding.ASCII.GetString(mem.ToArray(), 0, 9) == "newvendor")
                    {
                        string stream = System.Text.Encoding.ASCII.GetString(mem.ToArray());
                        string[] split = stream.Split(new Char[] { '|' });
                        mysql.insertVendor(split[1], split[2], split[3], split[4]);

                        Console.WriteLine("Ein neuer Lieferant (" + split[1] + ") wurde angelegt. " + now.ToString("dd.MM.yyyy HH:mm"));
                        instanceOfClass.Send(System.Text.Encoding.ASCII.GetBytes("erfolgreich"));
                    }
                    else if (System.Text.Encoding.ASCII.GetString(mem.ToArray(), 0, 17) == "insertordernumber")
                    {
                        string stream = System.Text.Encoding.ASCII.GetString(mem.ToArray());
                        string[] split = stream.Split(new Char[] { '|' });
                        mysql.insertIntoDatabase(split[1], split[2]);

                        Console.WriteLine("Der Artikel (" + split[1] + ") wurde für den Lieferant (" + split[2] + ") hinzugefügt. " + now.ToString("dd.MM.yyyy HH:mm"));
                        instanceOfClass.Send(System.Text.Encoding.ASCII.GetBytes("erfolgreich"));

                    }
                    //Console.WriteLine("send {0} bytes",mem.Length);
                    //instanceOfClass.Receive(mem.ToArray());
                    mem.Seek(0, SeekOrigin.Begin);
                    mem.SetLength(0);
                    TimeOut = 0;

                    //Console.WriteLine("4 - jhadbfhibsdb");
                }
                else
                {
                    TimeOut++;
                    Thread.Sleep(SleepTime);
                }
            }
            instanceOfClass.closeConnection();
            socket.Close();
            socket = null;
            serverThread.Abort();
        }
--
Vielen Dank

LG
Kevin
private Nachricht | Beiträge des Benutzers
Mallett
myCSharp.de - Member



Dabei seit:
Beiträge: 176

beantworten | zitieren | melden

Statt for(;;) würde ich eher sowas wie while(!shutdown) nehmen, dann kannst du den Server auch gezielt beenden indem du das shutdown flag setzt. Ansonsten passts doch. Der ganze Kram in if (mem.Length > 0) geht auch einfacher, wenn Du einen TcpListener / TcpClient und dazu StreamReader/StreamWriter verwendest.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Mallett am .
private Nachricht | Beiträge des Benutzers