2017-01-14 7 views
0

Ich programmiere ein Multiplayer-Spiel und ich habe eine harte Zeit mit der Größe von UDP-Paketen. Ich möchte mehrere Feindstatistiken (HP, Position, ID) über UDP-Pakete senden. Hier ist der wichtige Code-Teil:UDP-Paket: Wie werden verschiedene Datentypen in einem Paket gesendet?

Byte[] datagramPacketData = ("11" + String.valueOf(entityAmount) + "," + gamename + "," + username + entitiesToBeSent).getBytes(); 

Wie Sie sehen können, ich alle Daten in einen String an Zusammenführung und dann konvertieren byte [], bevor ich es senden. Aber Chars verbrauchen viel mehr Bytes als kleine Ints (für ID und Position) und Longs (HP). Zum Beispiel: ein Mob hat 2.000.000 PS. diese Nummer wird 7 Zeichen (= 7 Byte) verbrauchen, aber es würde nur 4 Byte für lange benötigen. Wie kann ich all diese Daten senden, indem ich weniger Bytes benutze, ohne Objektströme zu verwenden?

Ich würde mich sehr über einige Vorschläge freuen! Vielen Dank im Voraus.

+0

Konvertieren Sie jeden einzelnen Chunk in Bytes, anstatt sie in Strings und dann alle in Bytes auf einmal zu konvertieren? – Natecat

+0

Wie parsen Sie sie dann auf der Empfangsseite? Ich meine, wie kann ich wissen, welcher Teil von Bytes was ist. Weil ich nur ein Byte erhalten werde [] mesh – Madness

+1

Es gibt mehrere Dinge, die Sie tun könnten. Sie können ein Standardlängenpaket erstellen, so dass Bereiche von Positionen im Bytearray konsistent bestimmten Variablen entsprechen, oder Sie könnten Bytes an das Array anhängen, die Ihnen die Position des Anfangs jeder Variablen usw. mitteilen. – Natecat

Antwort

0

Erstens, vorausgesetzt, dass Ihre Daten klein genug sind, um in ein einzelnes Paket zu passen, ist es unwahrscheinlich, dass die Länge der UDP-Nachricht einen großen Unterschied macht. Ich würde empfehlen, dass Sie sich nicht mit dem Problem befassen, es sei denn, Sie haben konkrete Beweise dafür, dass die Paketgröße ein kritisches Thema ist. d. h. harte Benchmarking-Ergebnisse, die zeigen, dass Sie nicht in der Lage sind, die minimale Übertragungsrate zu halten, die für das Spiel oberhalb einer bestimmten Paketgröße erforderlich ist. (Das Optimieren für ein Problem, das nicht wirklich existiert, ist eine Verschwendung von Aufwand.)

Wenn Sie über die Nachrichtenlänge besorgt sind, sollten Sie Vergleiche mit String-Codierung (wie oben) und Binärcodierung; z.B. wie Sie mit DataInputStream und DataOutputStream bekommen würden.

  • einem byte wird als ein einzelnes Oktett
  • ein short oder char als zwei Bytes werden verschlüsselt
  • usw.

Siehe DataOutputStreamjavadocs Einzelheiten codiert werden.

Verwenden Sie keine Objektströme. Sie verwenden die gleiche binäre Codierung wie DataOutputStream, aber es gibt erhebliche zusätzliche Gemeinkosten für die Kodierung von Informationen und Objektidentitäten.

+0

danke! :) Ich werde von String-Codierung zu Binärcodierung wechseln, das sollte meine Bedenken lösen! :) – Madness

+0

Aber zuerst überprüfen Sie, ob Ihr Anliegen begründet ist. Wenn dies nicht der Fall ist, wird Ihre Änderung keinen großen Unterschied machen. Es wird Zeitverschwendung sein. –

+0

Es ist gut begründet :) thx. – Madness

0

Ich habe meinen Versuch jetzt gemacht und es funktioniert für String, aber nicht oder lang. Ich kann den Fehler nicht selbst herausfinden, vielleicht kann einer von Ihnen den Fehler finden? Hier ist es:

Auf Senderseite:

byte[] data = new byte[1024]; 
     int i = 0; 

     String packetNumber = "25"; 

     ByteBuffer buffer0 = ByteBuffer.allocate(2); 
     buffer0.put(packetNumber.getBytes()); 
     byte[] numberInByte = buffer0.array(); 

     int x = 0; 
     for (int k = i; k < numberInByte.length; k++) { 
      data[k] = numberInByte[x]; 
      x++; 
      i++; 
     } 

     long life = 2000000; 

     ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); 
     buffer.putLong(life); 
     byte[] lifeInByte = buffer.array(); 

     x = 0; 
     for (int k = i; k < lifeInByte.length; k++) { 
      data[k] = lifeInByte[x]; 
      x++; 
      i++; 
     } 

Auf Empfängerseite:

ByteBuffer byteBuffer = ByteBuffer.wrap(data); 

     byte[] packetNumber = new byte[2]; 
     byteBuffer.get(packetNumber); 
     System.out.println(new String(packetNumber)); 

     long life = byteBuffer.getLong(); 
     System.out.println(life); 

Der Ausgang ist: 25 (was richtig ist) 1.966.080 (was nicht ganz 2000000 , aber warum?)

+0

Verwenden Sie DataOutputStream + ByteArrayOutputStream usw. Es ist einfacher. –

Verwandte Themen