Autor Beitrag
vampir
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Sa 05.12.09 18:32 
Hi

Folgendes Problem. Ich entwickle grad ein Chat in c#. Ich sende also Pakete mit einem Code und die Darauffolgenden Daten.
Eine Nachricht ist zb so aus: "0100!Hallo Server". 0100=Code für Nachricht, !=Splitchar, Rest=Message
Also durch string[] command = msg.Split('!'); erhalte ich die einzelnen Pakete.

Wenn ich jetzt aber drei Pakete nacheinander Losschicke...

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
private void button1_Click(object sender, EventArgs e)
{
   Client.Send("0100!Hallo Client =)");
   Client.Send("0100!Heeey");
   Client.Send("0100!TESTMSG dsgfdsggfg.");
}


Dann werden einige Pakete nicht einzeln verschickt, sondern zusammengefasst.

Send Function der Client Klasse:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
public static void Send(string msg)
{
   byte[] buffer = AsciiEncoder.GetBytes(msg);

   networkStream.Write(buffer, 0, buffer.Length);
   networkStream.Flush();
}


Es wäre ja zu erwarten, dass drei einzelne Pakete ankommen, aber es sind meistens nur zwei:
"0100!Hallo Client =)" und
"0100!Heeey0100!TESTMSG dsgfdsggfg."

Ich weiss nicht warum das passiert. Theoretisch ist das ja gar nicht möglich.
Vielleicht ist networkStream.Flush() nicht schnell genug,
so dass es die 2. Message vor dem abschicken auch noch reinschreibt?

Hoffe ihr könnt mir helfen.

mfg
vampir

PS: 1 Beitrag in 4 Jahren - nicht schlecht oder? :)
vampir Threadstarter
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Di 08.12.09 18:59 
Ach kommt schon ;)

Das erste Paket wird immer einzeln versendet, alle andern
kommen als einziges Paket an.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 08.12.09 19:37 
Zitat:
Vielleicht ist networkStream.Flush() nicht schnell genug,

Es wird wohl eher so sein das beim Empfänger dein networkStream.Read() (oder was auch immer du da äquivalentes machst) spät dran ist. Heißt während dem Read befindet sich einfach schon mehr als ein Paket im Empfangsbuffer. Wenn du schon einen expliziten Nachrichtentrenner hast (dein !) solltest du den dann auch beim Empfänger einsetzen und die Nachrichten wieder trennen.
vampir Threadstarter
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Di 08.12.09 20:04 
Hast recht, das ist eigentlich logischer.

Der Empfang läuft in einem eigenen Thread (vereinfachter Code):

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
while(true)
{
   int bytesRead = 0;
   byte[] ReceivedData = new byte[8145728];

   //Warte bis Nachricht erhalten wird
   bytesRead = networkStream.Read(ReceivedData, 08145728);

   string msg = AsciiEncoder.GetString(ReceivedData, 0, bytesRead);
   MessageManager.Work(msg);
}


Also die einzelnen Pakete trenne ich noch gar nicht mit einem Nachrichtentrenner, sondern die Daten in den einzelnen Paketen selbst.
Aber am besten würde ich wohl die Nachrichten mit einem weiteren Trenner trennen (zb '?'). Oder?

mfg
Vampir

Nachtrag:
Habs jetzt so gemacht! Vor jeder Nachricht ein '?' Seperator.
Funktioniert jetzt super!

Danke für die hilfe!
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Mi 09.12.09 10:18 
Hallo,

du solltest bedenken, dass wenn dein Empfänger nicht "schnell" genug arbeitet und deshalb Daten größer 8145728 Byte lesen will (was eigentlich nie vorkommen sollte) er einen Teil der Nachricht verliert. Ich lesen in solchen Fällen bis zu einem bestimmten Zeichen. In der Regel nehme ich das Newline-Zeichen. Dann kann man bequem ReadLine machen und bekommt den nächsten Command.

Gruß Daniel

PS: Hoff man versteht den Text, bin noch leicht übermüdet ;)
vampir Threadstarter
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Mi 09.12.09 19:19 
Danke für den Hinweis.