Laden...

Sendeprobleme zwischen Server und Client

Erstellt von Pioneer17 vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.846 Views
P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 11 Jahren
Sendeprobleme zwischen Server und Client

Hallo zusammen

Ich habe ein Problem, dass der Server teilweise keine Meldungen an den Client schicken kann.
Der Aufbau ist wie folgt:

Server:
Der Server horcht auf alle einkommenden Verbindungen auf einem Port. Sobald eine ankommt wird die TCPClient Instantz in ein neuen Thread übergeben und wartet dort dann auf einkommende Nachrichten.

Client:
Der Client verbindet sich zum Server und auch dieser läuft in einem eigenen Thread der bei


string str = new StreamReader(this.client.GetStream()).ReadLine();

wartet bis etwas ankommt.

Nun ist es teilweise so, dass zwar der Client noch Nachrichten an den Server senden kann und diese vom Server auch verarbeitet werden, jedoch der Server nichts an den Client schicken kann.

Als Übertragung verwende ich einen StreamWriter (Client)


            StreamWriter writer = new StreamWriter(client.GetStream());
            writer.WriteLine("senden");
            writer.Flush();

Auf der Serverseite


            NetworkStream stream = null;
            try
            {
                stream = clientByNames[receiverName].GetStream(); // Da ist die Clientinstanz dahinter
            }
            catch
            {
                //Fehler
            }
            if (stream != null)
            {
                StreamWriter writer = new StreamWriter(stream);
                stream.Flush();
                writer.WriteLine("send");
                writer.Flush();
             }

Ich habe mich bei dem Server eingeklinkt und konnte im Debugmodus sehen (wenn ich das richtig intepretiert habe) das er bei writer.Flush() stehengeblieben ist.

Die Frage ist nun, ob diese Infos reichen um mir einen Anhanltspunkt geben zu können wo das Problem liegen könnte, oder ob das Problem "bekannt" ist und ich einen Fehler bei der Implementierung mache.

Evtl. müssen zuerst noch die richtigen Fragen gestellt werden 😉

Besten Dank für eure Hilfe

Z
403 Beiträge seit 2007
vor 11 Jahren

Hallo Pioneer17,

vor kurzem gab es ein ziemlich ähnliches Problem.
Schau mal hier: Socket Server mit Threads, vom GUI aus dem Client etwas schicken

Client:
Der Client verbindet sich zum Server und auch dieser läuft in einem eigenen Thread der bei

string str = new StreamReader(this.client.GetStream()).ReadLine();  

Warum erstellst du den StreamReader hier immer wieder ?

André

P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 11 Jahren

Hi TheGear

danke für den Hinweis.

Es gibt keinen speziellen Grund warum ich den StreamReader immer wieder erstelle. Das wäre ja "nur" eine Speicheroptimierung, oder?

Betreffend des anderen Beitrages, sehe ich keinen Zusammenhang mit meinem Problem. Ich muss es sowieso einbisschen im Auge behalten, da es ja nicht immer auftritt.
Ich habe in meinem Programm die komplette Kommunikaitons geändert, evtl. kam dieser Fehler noch von "Altlasten" vom Alten Code. Mittlerweile ist der "Umbau" soweit fertig und bis jetzt ist es nicht wieder passiert.

P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 11 Jahren

Leider ist es wieder passiert...

ist das eigentlich so, dass händisch einen Sleep eingebaut werden muss, bevor ich z.B. die Verbindung beende, oder bei einem Connect, bevor ich die erste Meldung schicke?

Wo ich porbleme hatte war wenn ich eine Meldung geschickt hatte und gleich darauf die Verbindung mit .Disconnect beendet habe ging die letze Meldung teilweise nicht durch. Seit dem ich vor dem Disconnect einen Sleep von 500ms eingebaut habe, ist das nicht mehr passiert.

Muss ich das ggf. auch vor dem ersten senden einer Nachricht machen?
Ist das "normal"?

1.346 Beiträge seit 2008
vor 11 Jahren

Das immer neue erstellen des StreamReaders ist nicht nur eine optimierung. Der StreamReader speichert Daten zwichen. Wenn du dann einen neuen erstellst gehen die gecachten Daten verloren

P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 11 Jahren

Als Kommunikations- "Vorlage" habe ich das Projekt Chatprogramm verwendet.

Server:


private void ListenToClient(object aClient)
        {
            TcpClient senderClient = (TcpClient)aClient;
            bool flag = true;
            while (flag)
            {
                try
                {
                    string str = new StreamReader(senderClient.GetStream()).ReadLine();
                    if (!string.IsNullOrEmpty(str))
                    {
                        this.ParseReceivedTelegram(senderClient, str);
                    }
                    else
                    {
                        flag = false;
                    }
                }
                catch (IOException)
                {
                    flag = false;
                }
            }
        }

Da ist es doch richtig, dass der StreamReader immer wieder neu erstelt wird, oder? Es werden ja sowiso alle Daten gelesen und gleich weiter gegeben, oder sehe ich das falsch?

Mein Projekt habe ich soweit umgestellt, dass es mehrere Server gibt.
Bsp.:
Ich habe eine Hauptapplikation "Service" und mehrere Hilfsprogramme die verteilt sind. Entgegen der Norm, sind bei mir diese Hilfsprogramme die Server (Klassen) und das Hauptprogramm der Service eigenltich der Client. Der Service verbindet sich mit den Hilfsprogrammen.
Vom Service her können aber mehrere Verbinungen pro Hilfsprogramm hergestellt werden.

Wenn das Problem jedoch auftritt, dass die Hilfsprogramme (Server) nichts mehr an den Service (Client) senden können betrifft das alle Server. D.h. der Fehler dürfte nicht serverseitig sein, sondern eher clientseitig.

Z
403 Beiträge seit 2007
vor 11 Jahren

Hallo Pioneer17,

Da ist es doch richtig, dass der StreamReader immer wieder neu erstelt wird, oder? Es werden ja sowiso alle Daten gelesen und gleich weiter gegeben, oder sehe ich das falsch?

Nein. Es wird ein neuer Stream erzeugt der dann bis zum nächstem Zeilenumbruch (eines Strings) Daten des zugrunde liegenden Streams liest.

Allerdings wird bei Operationen wie beispielsweise Close auch der zugrundeliegende Stream geschlossen.

So wie du es derzeit machst, sind alle Vorteile von Streams für die Katz.

Wo ist denn das Problem den StreamReader nur einmal zu erstellen ?

André

P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 11 Jahren

Hab die ganze Geschichte nun soweit umgebau, dass ich nun direkt in den Stream schreibe, bzw lese mit stream.write / stream.read.

weiter hatte ich das problem, dass mehrere Datensätze im Streamreader waren, welche ich mit jeder neuen Instanz "zerstört" habe. Das war der Grund, warum ich teilweise gewisse Sachen nicht empfangen habe und teilweise nur die Hälfte.

Nun seit dem umbau funktioniert alles so wie ich mir das vorgestellt habe.

Nun erstelle ich einen Stream pro Verbindung und merke mir diese in einem Dic, damit ich dann später wieder etwas in den stream zurück schicken kann. Somit wird für die Lebensdauer der Verbindung lediglich noch ein Networkstream-Instanz gespeichert.