Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

16.03.2012, 01:55

Java NIO gemischt mit Sockets

Hiho, ich sitze hier an einem Projekt (ein Spiel natürlich), an dessen Netzwerkteil sich jemand zu schaffen gemacht hat und ich darf es nun richten ;)
Da der Netzwerkcode im ganzen Projekt mit drin Steckt kann ich ihn nicht ohne weiteres Posten, versuche aber die wichtigen Stellen zu beschreiben bzw. zu kopieren, und sollte es notwendig sein, setzte ich ein kleines Testprojekt auf, aber vllt. geht es ja auch so.

Im Multiplayerteil startet der Host einen Server und connectet selbst darauf, danach alle anderen Clienten.
Beim Clienten wird ein normaler Socket verwendet, auf welchen in jeweils einem eigenen Thread geschrieben wird (also auf den durch mSocket.getOutputStream() gegebenen OutputStream), bzw. von welchem gelesen wird (von seinem InputStream).
Auf der Serverseite verwenden wir für jeden Clienten einen eigenen SocketChannel. Zum lesen erzeugen wir einen neuen ByteBuffer und schreiben alle erhaltetenen Daten darauf, danach lesen wir von dem ByteBuffer die Daten in ein Paket. Das schreiben auf dem Channel läuft ähnlich ab: Paket -> ByteBuffer -> Channel.

Im Grunde funktioniert das ganze auch ein wenig, Verbindung herstellen und Daten hin- und herschicken funktioniert auch soweit. Aber: Sendet der Client Daten los, im Test 3 Integer, kommen diese "verdreht" an. Also:
Der Client sendet folgende 12 Bytes, jeweils getrennt durch ein "|":

Quellcode

1
0|0|0|10|0|0|0|-102|0|0|0|-91

Auf dem Server kommt aber folgendes an:

Quellcode

1
10|0|0|0|-102|0|0|0|-91|0|0|0


Irgendwie erinnert mich die Geschichte ein wenig an das Endian-"Problem", zum Beispiel bei C++, aber das entfällt hier ja.
Irgendwelche einstellungen wurden nicht vorgenommen. Haben wir eine übersehen? Oder wie kommt sonst dieses Verdrehen von 4-Byte-Blöcken zustande?

mfg

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

2

16.03.2012, 07:24

Warum sollte das Endian-Problem entfallen? Little-Endian ist nunmal "verkehrt" herum.
Und ich denke mal, es wird auch in Java Funktionen geben, um ein byte-Array wieder in einen primitiven Datentypen zu konvertieren.

3

16.03.2012, 08:17

Ich habe gelesen, dass es sich bei Java immer strikt um Big-Endian handeln soll, womit das eben entfallen dürfte.
Ja die gibt es, beim Server mit dem SocketChannel, wo man ByteBuffer rumschickt und empfängt, gibt es auf dem ByteBuffer (z.B.) die Funktionen getInt und putInt, beim DataInputStream/DataOutputStream gibt es putInt respektive readInt.
Das Problem ist aber nun dass sich das Empfangene immer 4-Byteweise verdreht hat, und somit aus einer gesendeten "10" eine empfangene "167772160" wird.

EDIT:

Na gut, ich nehm das gesagte zurück. Anscheinend empfängt der SocketChannel im Littleendian-Format, ein "buffer.order(ByteOrder.LITTLE_ENDIAN);" behebt das ganze. Jetzt muss ich nur noch rausfinden, wieso die Funktion SocketChannel.read(buffer); zwar 12 Bytes liest, aber nur angibt 9 Bytes gelesen zu haben..

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »gummiwipfel« (16.03.2012, 11:23)


Noctarius

Treue Seele

Beiträge: 120

Wohnort: Düsseldorf

Beruf: Manager of Developer Relations at Hazelcast, Inc. & Consultant for Scaleable Gameserver Systems

  • Private Nachricht senden

4

16.03.2012, 17:29

Du kannst Endian-Encoding für einen ByteBuffer einstellen. Generell würde ich per DataOutput / DataInput (für Socket) und WriteableByteChannel / ReadableByteChannel (für NIO) arbeiten. Dann sollte (im Standardfall) jeweils BigEndian vorkonfiguriert sein.

Werbeanzeige