2016-04-19 6 views
0

TCP ist strombasiertes Protokoll. Um diesen Stream in meine Nachrichten zu konvertieren, sende ich die Größe jeder Nachricht mit der Nachricht selbst. Auf Serverseite lese ich zuerst die ersten zwei Bytes der Nachricht, die die Größe haben. Dann erstelle ich ein Byte-Array, dessen Größe der Größe entspricht, die gerade gelesen wurde. Dann lese ich die Bytes in dieses Array. Aber aus irgendeinem Grund werden mehr Bytes gelesen als spezifiziert. Wie kann ich genau die gleiche Anzahl an Bytes lesen, die ich angegeben habe?Socket-Programmierung: Wie kann ich eine bestimmte Anzahl von Bytes aus dem Puffer lesen?

Hier ist mein Code:

while (true) 
{ 
    data = null; 
    length = null; 

    size = new byte[2]; 

    handler.Receive(size); 

    length += Encoding.ASCII.GetString(size, 0, 2); 
    System.Console.WriteLine("Size: " + Int32.Parse(length)); 

    bufferSize = Int32.Parse(length) + 2; 
    bytes = new byte[bufferSize]; 

    handler.Receive(bytes); 

    data += Encoding.ASCII.GetString(bytes, 0, bufferSize); 
    System.Console.WriteLine("Data: " + data); 
} 

Dies ist mein Server in Windows-PC ausgeführt wird, in C# geschrieben. Mein Client läuft in Android-Handy, in Java geschrieben.

+1

a) warum Sie verwenden '' Länge + = ... ' 'anstelle von' 'length = ...' '? b) Warum die '' + 2'' in '' bufferSize = Int32.Parse (length) + 2; ''? c) Sie erwarten, dass die Länge 2 ASCII-Zeichen beträgt. Schickt der Client sie als 2 Bytes? Oder vielleicht eine 4-Byte-Ganzzahl? – f1sh

+0

a) Ich nehme an, dass 'length + = ...' dasselbe wie 'length = ...' ist, da die length jedes Mal auf null gesetzt wird. b) Es handelt sich um Newline-Zeichen, die vom Client gesendet werden. –

+0

'Länge' muss' int' nicht 'string' sein. Vielleicht kommst du von 'python' oder' javascript' Welten. – i486

Antwort

1

Es ist unklar, warum Sie das Hinzufügen von zwei auf die Größe, die übertragen worden ist - Sie haben bereits für die zwei zusätzlichen Bytes entfielen zum Speichern der Länge während dein vorheriger Empfang Also würde ich die +2 loswerden.

Sie müssen auch die bereits in Ihrer Frage angegebene Tatsache berücksichtigen - TCP ist eine Folge von Bytes, keine Nachrichten. So ist es nie garantiert, ob ein Anruf an Receive eine ganze "Nachricht" oder nur einen Teil von einem (oder möglichen Teile von mehreren Nachrichten) abrufen wird. Daher müssen Sie sicherstellen, dass Sie den Rückgabewert von Receive respektieren.

Wir können wahrscheinlich neu schreiben Ihren Code wie:

while (true) 
{ 
    data = null; 
    length = null; 

    size = ReceiveExactly(handler,2); 

    length = Encoding.ASCII.GetString(size, 0, 2); //Why +=? 
    bufferSize = Int32.Parse(length); //Why + 2? 
    System.Console.WriteLine("Size: " + bufferSize); 

    bytes = ReceiveExactly(handler,bufferSize); 

    data += Encoding.ASCII.GetString(bytes, 0, bufferSize); 
    System.Console.WriteLine("Data: " + data); 
} 

Wo ReceiveExactly etwas wie folgt definiert ist:

private byte[] ReceiveExactly(Socket handler, int length) 
{ 
    var buffer = new byte[length]; 
    var receivedLength = 0; 
    while(receivedLength < length) 
    { 
     var nextLength = handler.Receive(buffer,receivedLength,length-receivedLength); 
     if(nextLength==0) 
     { 
     //Throw an exception? Something else? 
     //The socket's never going to receive more data 
     } 
     receivedLength += nextLength; 
    } 
    return buffer; 
} 
2

eine bestimmte Menge an Bytes, die die Methode

Socket.Receive(Byte[], Int32, Int32, SocketFlags) 

anstatt Socket.Receive(Byte[]) verwenden zu empfangen. siehe spec here

Ich vermute, Sie wollen etwas, wie

int len = Socket.Receive(bytes, 0, bufferSize, SocketFlags.None); 

data += Encoding.ASCII.GetString(bytes, 0, len); 
System.Console.WriteLine("Data: " + data); 
+0

Die ersten beiden Bytes haben die Größe des Rests der ursprünglichen Nachricht. Ich konvertiere diese Bytes in eine Zeichenfolge und parse dann diese in int.Dann erstelle ich einen Puffer dieser Größe, um die ursprüngliche Nachricht im nächsten Empfangsanruf zu lesen. –

+0

Ihre Lösung hat bei mir nicht funktioniert. –

Verwandte Themen