With Java Sockets you send and receive messages through the InputStream and OutputStream classes. The most basic tutorial reads lines of strings from these streams (as in a chat application or something).

What if you would like to send a bunch of primitive data types? One would think that wrapping the Streams into a DataInputStream and DataOutputStream would work - but here's a problem. Each time you write to these streams the message is sent directly! You can't bunch up a, say, 1 Byte and 2 Integers and a String ( in that order ) and then send the 'package' as whole through the Sockets Streams.

What I've been accustomed to from another language, is that you build a 'package' first, and then send the package - like this f.ex:

1 2 3 4 5 6

clearbuffer();writeByte(1); // Used to identify what sort of message this iswriteInt(x);writeInt(y);writeString("Teddybears");sendMessage(socket.outputStream);

This package would be extremely light as it would only be the size of the bytes that is sent.

In Java, I've noticed people sending whole Objects through Serialization. Which, to me, seems highly unnecessary - and a lot more heavy in size f.ex:

and to identify what kind of message is sent you use the 'instanceof' keyword, and for each different type of message you create a new class.

I would think that this Java solution, while it might work, creates a lot more unnecessary weight in my packets and that there should exist a more controlled way, like the former solution, in Java. Is there?

Regarding not sending data immediately:1. use BufferedOutputStream and .flush() when you're done.

o.O --> re-reads about Buffered Streams.

Looking closer at BufferedOutputStream and BufferedInputStream, they both write and read bytes of data.. which is good. How would you convert these into primitive data types?

I'm assuming you would use a Scanner for this, but how would you know in what order the bytes are supposed to be read if you can't figure out the message ID that... that we put in front of every single message as a byte value... kind of answered my own question there

So to lay it all out, would this be a suitable design in Java, using Scanners

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Scanners = null;try {s = newScanner (newBufferedInputStream ( socket.getInputStream() );byteb = s.nextByte(); /* we know the first value is going to be a byte that is going to function as the ID to identify what kind of message it is and therefore we will know what values to read from it further down*/if (b == 1) readPosition(s);} finally {if (s != null) s.close(); // close the scanner}

Scanner is slow, use BufferedReader.As for writing, you can wrap an ObjectOutputStream around the output stream since it can write primitives, strings, and objects.

EDIT: You can also take a look at my networking library, which uses a Packet system and handles the sending for you.

The BufferedReader can't read primitives though. The DataInputStream ( and Scanner ) does however... so changing the Scanner into DataInputStream...

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

try {DataInputStreamdin = newDataInputStream (newBufferedInputStream ( socket.getInputStream() );bytemessage_id = din.readByte();/* we know the first value is going to be a byte that is going to function as the ID to identify what kind of message it is and therefore we will know what values to read from it further down*/if (message_id == 1) readPosition(din);} catch (IOExceptione ){ }

Haha, I was about to say that counterp's Buffer class looks like java.nio.ByteBuffer.

@OPAt this stage, it is best for you to use java.nio.channels.SocketChannel as you can just use the ByteBuffer class to read and write. However, ByteBuffer does not have a way to write Strings so you will have to get the bytes from a string:

Yeah, I guess you can compare it to NIO byte buffer, except mine is faster and no annoying flip method, it also doesn't have some of the same methods, but it has support for signed and unsigned types (or as much support as you can get in java). You can also specify the size of a packet with mine using the start and end methods (if you have a packet with varying size and it is important that you know how big it is).

EDIT: You can also take a look at my networking library, which uses a Packet system and handles the sending for you.

I had a moderately (didn't understand eveything) thorough (took me 2 hours) look through your library (the networking bits) - it looks very clean. Since I'm just now, as a result of this thread, getting to know the java.nio package it still is a bit over my head. But I found other outlets for tutorials and explanations, this blog post in particular was very informative for me since I was already accustomed to the java.io package and how the java.net sockets work.http://blogs.oracle.com/slc/entry/javanio_vs_javaio

@OPAt this stage, it is best for you to use java.nio.channels.SocketChannel as you can just use the ByteBuffer class to read and write. However, ByteBuffer does not have a way to write Strings so you will have to get the bytes from a string:

1

byte[] data = "this is my string".getBytes("UTF-8");

I was slightly unsure on how to read Strings, thanks for clearing that up. Of course the byte size of a string will vary but since I can identify what type of message is incoming I'll be able to add the strings size in front of the string in the buffer as a byte value (for example) and that way know how many bytes to read.

The biggest difference between the old Socket from java.net and the new SocketChannel* from java.nio is that SocketChannel implements non-blocking mode. Which means that the program won't "lock up" when trying to read for input like it would on the old java.net Socket (you would have to make a new Thread to listen for input in order to circumvent our program from locking up).[size=6pt]*The java.nio SocketChannels are built from the old java.net Sockets.[/size]

Here's a brief revealing outtake from the blog post linked above:

Quote

SocketChannel

SocketChannel is different to FileChannel: The new socket channels can operate in nonblocking mode and are selectable. It's no longer necessary to dedicate a thread to each socket connection, Using the new NIO classes, one or a few threads can manage hundreds or even thousands of active socket connections with little or no performance loss. It's possible to perform readiness selection of socket channels using a Selector object.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org