Do what you like, just keep in mind that ObjectInput/OutputStream are much slower than using byte streams due to unessecary data being sent.
Renoria, I totally agree that it’s sending a lot of excess information, but what you suggested is a lot of manual conversion for the developer where Reflection can take all the pain away for you.
Yeah, but sending all that other crap (package names, method names) etc is a big waste of bandwidth, while using a simple byte stream writer doesn’t use nearly as much, and you can actually control what is being sent/recieved. I would probably wrap the InputStream into a java.io.DataInput/OutputStream to use methods such as writeInt, writeByte, writeShort, readInt, readShort etc.
You could also use Apache MINA, xSocket or Riven’s NIO Wrapper, or any other NIO/IO Lib.
Ok, guys I have a serious problem now. I really can’t seem to solve this mystery.
Whenever I send strings, string-arrays or the like via ObjectOutputStream.writeObject() it goes super smooth(0-1 ms delay on localhost), but then whenever I send byte[]'s with the write() command, I get a delay of 80 ms. It is only delayed when the server sends back another byte[] to the client. I have 1 server and one client right now, and I have spent hours without finding the problem…
private void handleCommon() {
sendObject("ok");
ActorState as = new ActorState();
as.bUnSerialize(getBytes());
store.putState(name, as);
// sendBytes(store.getState(name).bSerialize());
}
}
in the above code, I have commented out the sendBytes command, and the delay is 1 ms for sending and receiving the array. When I uncomment it so it is called I get 80 ms of delay. Can someone tell me what could be wrong? It shouldnt take longer for my server to send the bytes than for my client right?
What makes this weird is the fact that it works for String[] arrays which in my world should be MUUUCH bigger than byte-arrays… The data in the byte[] arrays is just 4 doubles an 2 ints.
Here is some more code specific to this problem(I’m sorry its really nasty cuz im debugging it right now):
private void sendBytes(byte[] b) {
try {
// out.flush();
out.write(b);
out.flush();
// System.out.println("server>" + msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
private byte[] getBytes() {
try {
byte[] b = new byte[800];
in.read(b);
return b;
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
return null;
}
Perhaps the problem is the way you read the bytes… you’re asking the inputstream for up to 800 bytes, maybe it’s sitting there waiting for a tiny bit to see if there are any more to come. See if using read(byte[], int, int) fixes it by specifying exactly how many bytes you’re expecting.
Cas
pretty sure this isnt the problem. I used to do it using “redObject” and “writeObject” casting them for whatever I was sending. This gave me the exact same delay(80 ms). And I dont think i’m asking for anything by handing in the 800 size aray, because it just edits the first 0-n spots in the array(one would think), so as long as the array is big enough, i’m safe.
How about you write the length of the array as a byte/short then write the elements using for.
Write using:
writeByte/Short(length)
for (int i = 0; i<thing.length; i++) {
writeByte/whatever(thing[i]);
}
Read using:
byte/short num = readByte()/Short();
byte[] thing = new byte[num];
for (int i =0; i<num; i++) {
thing[i] = readByte()/whatever();
}
OR you could :
private byte[] getBytes() {
try {
byte[] b = new byte[in.available()]; //how much data available?
in.read(b);
return b;
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
return null;
}
OR if you wanna be newbie:
private byte[] getBytes() throws Exception {
byte[] r = new byte[2048];
byte haha;
int i = 0;
while ((haha = in.read()) != -1) { //-1 delimiter
r[i] = haha;
i++;
}
byte ret[] = new byte[r.length];
for (int k = 0; k < r.length; k++) {
ret[k] = r[k];
}
return ret;
}
Object{Input|Output}Stream is pretty highlevel, which means there can be a lot of things happening when you write(byte[]).
You could use Data{Input|Output}Stream (with readUTF/writeUTF) and see how that performs.
Did you turn OFF Nagle's Algorithm? ( Socket.setTcpNoDelay(true) ) If so, every out.write(...) is 1 packet, so turn it ON: Socket.setTcpNoDelay(false), and flush() after the write.If you want to write a string, use this:
writeShort/Byte(str.length());
for (int i = 0; i < str.length(); i++) {
writeByte(str.charAt(i));
}
Then to read:
char[] read;
int len = readShort/Byte();
read = new char[len];
for (int i = 0; i < len; i++) {
read[i] = (char) (readByte());
}
return String.valueOf(read);
That reads the string.
My point was in reference back to Reflection, not using Java’s built-in Java Object Serialization crap. JGN uses custom reflection code so you don’t deal with any of the extra garbage that get sent across and it’s really a very simple concept.