Socket mit Network-Byte-Order (Motorola-Format)- Client und Server

25/05/2009 - 17:36 von Martin Greul | Report spam
http://www.fileuploadx.de/920207

http://www.fileuploadx.de/296194

Hallo Günter,
hallo Peter,
hallo Frank,

ja noch ein Thread, aber langsam kann ich nicht mehr und gebe auf.


also nutze da lieber:
BinaryWriter.Write(telegramm) // string
und
BinaryReader.ReadString()



Martin muss Network-Byte-Order verwenden. Zumindest hat er in einem
anderen
Thread (es gibt ja inzwischen einge Threads von ihm) geschrieben, dass er
das Protkoll ansich nicht ànderung kann.

Die String-Methoden von BinaryReader / BinaryWriter verwenden eine andere
Codierung der Lànge (eine Form von 7-Bit komprimiertem Integer). Somit ist
das ohne Protokollànderung keine Option.


Tansportprotokoll
. Größe der Nachricht in Bytes
. Größe des Nachrichtenkopfs (4 Byte)
Die Größe muss im Motorola-Format eingetragen werden.
http://www1.minpic.de/bild_anzeigen...4&ende

Wie Günter sagt, ich kann das nicht àndern!


Was ich will, einfach dass es geht, dass es lesbar ist.
Dann bleibt es einfach übersichtlicher.

// Prepare the message
byte[] data = Encoding.UTF8.GetBytes(msg);
int dataLen = data.Length + 4;
int len = IPAddress.HostToNetworkOrder(dataLen);

// Create a binary writer to be used for writing
BinaryWriter writer = new
BinaryWriter(_socket.GetStream());

// Write the length and the data to the stream
writer.Write(len);
writer.Write(data);
Was mir jetzt unklar ist, die Beziehung BinaryWriter zum Socket.
Günter hat es unten anders gemacht. Sicherlich übersichtlich.

Bitte seit doch so nett und es konkret anzuschauen? siehe Link, dann ist es
einfacher.
Einfach ein Beispiel.

Das von Günter ist übersichtlich und geht in die richtige Richtung.
Was fehlt, die 4 Bytes und das Reconnect im Fehlerfall.

void SendTelegram(Socket socket, string telegramm){

using(NetworkStream stream = new NetworkStream(socket)){
BinaryWriter writer = new BinaryWriter(stream);

byte[] data = System.Text.Encoding.UTF8.GetBytes(telegramm);

int lengthInNetworkOrder IPAddress.HostToNetworkOrder(data.Length);

writer.Write(lengthInNetworkOrdr);
writer.Write(data);
}

}


DANKE.

Grüße Martin
 

Lesen sie die antworten

#1 Günter Prossliner
25/05/2009 - 17:59 | Warnen spam
Hallo Martin!

ja noch ein Thread, aber langsam kann ich nicht mehr und gebe auf.



Bitte starte nicht für jede "Unterfrage" einen eigenen Thread. Das wird echt
unübersichtlich für alle!

Was ich will, einfach dass es geht, dass es lesbar ist.
Dann bleibt es einfach übersichtlicher.

// Prepare the message
byte[] data = Encoding.UTF8.GetBytes(msg);
int dataLen = data.Length + 4;



Wenn Du die konstante Lànge des Headers von 4 Bytes hinzufügen musst, dann
musst Du diese klarerweise beim Lesen von dem Stream wieder subtrahieren.

// Create a binary writer to be used for writing
BinaryWriter writer = new
BinaryWriter(_socket.GetStream());

// Write the length and the data to the stream
writer.Write(len);
writer.Write(data);
Was mir jetzt unklar ist, die Beziehung BinaryWriter zum Socket.



Der BinaryWriter ist einfach eine Wrapper-Klasse über den Stream welche dir
Arbeit abnimmt. So ist die Signatur der Write Methode (nur ein Array) z.b.
angenehmer als die Methode direkt auf den Stream. Der BinaryReader z.b. ruft
intern die .Read Methode des Stream mehrfach auf wenn der vorherige .Read
Aufruf nicht alle Daten geliefert hat. Es wird also der Return-Value
überprüft.

Das von Günter ist übersichtlich und geht in die richtige Richtung.
Was fehlt, die 4 Bytes



Beachte das +4 bzw. -4 in den Methoden.

void SendTelegram(Socket socket, string telegramm){

using(NetworkStream stream = new NetworkStream(socket)){
BinaryWriter writer = new BinaryWriter(stream);

byte[] data = System.Text.Encoding.UTF8.GetBytes(telegramm);

int lengthInNetworkOrder IPAddress.HostToNetworkOrder(data.Length+4);

writer.Write(lengthInNetworkOrdr);
writer.Write(data);
}

}

string ReadTelegram(Socket socket){

using(NetworkStream stream = new NetworkStream(socket)){
BinaryReader reader = new BinaryReader(stream);

int lengthInHostOrder IPAddress.NetworkToHostOrder(reader.ReadInt32());

byte[] data = reader.ReadBytes(lengthInHostOrder-4);

return System.Text.Encoding.UTF8.GetString(data);
}

}

... und das Reconnect im Fehlerfall.



Der Fehlerfall ist z.b. ein Timeout? Du musst dabei aber bedenken, dass der
Server da natürlich auch "mitspielen" muss. Wenn bei Dir der Client in ein
Timeout làuft und Du eine neue Verbindung aufbaust, dann musst Du dem Server
mitteilen, dass er Dir eben die Daten nochmal senden soll. Ist das im
Protokoll so vorgesehen? Sendest Du zuerst einen "Command" und ließt dann
das Ergebniss? Dann könnte man diese Sequenz wiederholen.

Wenn Du diese Details noch lieferst dann kann ich das auch in meinen
Postings berücksichtigen.


mfg GP

Ähnliche fragen