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
TCP Server hängt sich auf
progi123
myCSharp.de - Member

Avatar #avatar-3317.gif


Dabei seit:
Beiträge: 71
Herkunft: Süddeutschland

Themenstarter:

TCP Server hängt sich auf

beantworten | zitieren | melden

Heyho,

bei dem unten stehenden Server gibt es das Problem, dass die CPU-Auslastung auf 100% steigt wenn der Client verschwunden ist. Es wird keine Exception geworfen und wenn man SendMessageBack ausschaltet hilft es auch nicht weiter. Habt ihr einen Tipp für mich?


using System;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace TCPServer
{
    class Server
    {
        TcpListener tcpListener;
        Thread listenThread;

        public void Start()
        {
            tcpListener = new TcpListener(IPAddress.Any, 2000);
            listenThread = new Thread(new ThreadStart(ListenForClients));
            listenThread.Start();
        }

        private void ListenForClients()
        {
            tcpListener.Start();

            while (true)
            {
                TcpClient client = tcpListener.AcceptTcpClient();
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
        }

        private void HandleClientComm(object client)
        {
            while (true)
            {
                TcpClient tcpClient = (TcpClient)client;

                if (tcpClient.Connected)
                {
                    NetworkStream clientStream = tcpClient.GetStream();

                    byte[] message = new byte[tcpClient.ReceiveBufferSize];
                    int bytesRead = 0;

                    do
                    {
                        try
                        {
                            bytesRead = clientStream.Read(message, 0, tcpClient.ReceiveBufferSize);
                        }
                        catch (Exception)
                        {
                            break;
                        }

                        if (bytesRead == 0) break;

                        String result = ASCIIEncoding.ASCII.GetString(message, 0, bytesRead);
                        String ip = tcpClient.Client.RemoteEndPoint.ToString();

                        Console.WriteLine(ip + " " + result);

                        Thread sendThread = new Thread(new ParameterizedThreadStart(SendMessageBack));
                        sendThread.Start(tcpClient);

                        Thread importThread = new Thread(new ParameterizedThreadStart(ImportInDB));
                        importThread.Start(result);

                    } while (clientStream.DataAvailable);

                }
            }
        }

        private void SendMessageBack(object client)
        {
            try
            {
                TcpClient tcpClient = (TcpClient)client;
                NetworkStream clientStream = tcpClient.GetStream();

                byte[] message = ASCIIEncoding.ASCII.GetBytes("OK");
                clientStream.Write(message, 0, message.Length);
                clientStream.Flush();
            }
            catch (Exception)
            {
                Console.WriteLine("Client ist verschwunden.");
            }
        }

        private void ImportInDB(object data)
        { 
            //kommt noch
        }
    }
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von progi123 am .
private Nachricht | Beiträge des Benutzers
Lennart
myCSharp.de - Member



Dabei seit:
Beiträge: 416
Herkunft: Bawü

beantworten | zitieren | melden

Wird wahrscheinlich an deiner while(true) Schleife liegen. Verwende lieber Events wie hier zb: TCPComponents.
private Nachricht | Beiträge des Benutzers
progi123
myCSharp.de - Member

Avatar #avatar-3317.gif


Dabei seit:
Beiträge: 71
Herkunft: Süddeutschland

Themenstarter:

beantworten | zitieren | melden

Danke für den Hinweis. Hab das jetzt so gelöst:


if (tcpClient.Connected)
{
       //....
}
else 
{
       break;
}
Zitat
Wird wahrscheinlich an deiner while(true) Schleife liegen. Verwende lieber Events wie hier zb: TCPComponents.

Ein Eventbasierter Server wäre auch ganz interessant. Schau ich mir mal an.
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1.688

beantworten | zitieren | melden

Hallo,

korrekt wäre wahrscheinlich, statt


if (bytesRead == 0) break;

dies zu verwenden:


if (bytesRead == 0) return;
private Nachricht | Beiträge des Benutzers
Ruben
myCSharp.de - Member

Avatar #avatar-2971.jpg


Dabei seit:
Beiträge: 61
Herkunft: Hamburg

beantworten | zitieren | melden

Auf keinen Fall so lösen!!! ^^
Zitat von progi123
Danke für den Hinweis. Hab das jetzt so gelöst:


if (tcpClient.Connected)
{
       //....
}
else 
{
       break;
}
Denn ich habe das schon sehr oft durchprobiert.
Selbst wenn der Client auf der anderen Seite Close() gemacht hat, steht bei mit am Server immer noch tcpClient.Connectet == true.

Ich habe das dann so gelöst, dass mein Client einen Byte-Wert schickt und dadurch dem Server signalisiert, dass er jetzt die Verbindung trennt.

Nur habe ich dabei das Problem: Wenn der Server beendet wird, dann empfängt der Client keine Daten. Ich prüfe dazu immer networkStream.DataAvailable...
In der Zeit vor fünf Minuten ist Jetzt die Zukunft. Jetzt ist die Gegenwart. Die Zeit, in der ich zu erzählen begonnen habe, ist die Vergangenheit von Jetzt und die Zukunft von der Gegenwart der Zeit, fünf Minuten bevor ich zu erzählen begann.
private Nachricht | Beiträge des Benutzers
pohlmann
myCSharp.de - Member



Dabei seit:
Beiträge: 67
Herkunft: Willingen

beantworten | zitieren | melden

Das was ujr geschrieben hat ist (halb) richtig. Sobald sich ein (verbindungsorientierter) Client trennt - und dieser dann Shutdown() aufruft - kommt auf der gegenseite die Receive()-Methode durch und gibt die erhalten Byte-Anzahl von 0 zurück. Die 0 signalisiert eine Trennung der Verbindung.
Zitat
Selbst wenn der Client auf der anderen Seite Close() gemacht hat, steht bei mit am Server immer noch tcpClient.Connectet == true.
Klar. Irgendwie muss der Client ja dem Server signalisieren das er weg ist. Der Server wird auch weiterhin mit dem Client verbunden sein, aber nicht andersrum (weiteres senden würde zu SocketExceptions führen).

Bitte schreien wenn ich mich irre.
Religionskriege sind Konflikte zwischen erwachsenen Menschen, bei denen es darum geht, wer den cooleren, imaginaeren Freund hat
private Nachricht | Beiträge des Benutzers