Article View: aus.computers.java
Article #331Re: Java equivalent of C struct.
From: Paul Murray
Date: Sat, 21 Oct 2000 00:00
Date: Sat, 21 Oct 2000 00:00
104 lines
4503 bytes
4503 bytes
"Doug Rickard" <rickard@primus.com.au> wrote in message
news:39efb67d@news.iprimus.com.au...
> types in the packet. How can I do the equivalent in Java? The packet is a
> mix of bytes, ints, floating point, strings, etc. I have tried a couple of
> suggestions previously given in this newsgroup, but I found that each
> variable was being sent as a separate TCP packet, and the network
overheads
> were horrific.
> I need a way of building up large packets that I can send as
> one transmission. I need to be able to build in a Java client a packet
that
> will be understood by my existing C server.
I can think of a couple of things.
If you are simply serialising the class, that's a problem because
serialisation adds a bunch of data to the stream. You'll want to implement
your own rawRead and rawWrite methods.
For example, lets say your packet contains an int of data, an int of count,
then count items of other data. You want to hold this in java as a
java.util.List, but you don't want to serialize the List object
interface Raw {
void rawRead(DataInputStream in);
void rawWrite(DataOutputStream out);
}
MyPacket implements Raw {
public int data; // etc
List subpackets = new ArrayList(); // this list will contain subpackets
public void rawWrite(DataOutputStream out) {
out.write(data); // etc
out.write(subpackets.size());
for(int i = 0; i < subpackets.size(); i ++)
((Raw)subpackets.get(i)).rawWrite(out);
}
public void rawRead(DataInputStream in) {
data = in.readInt(); // etc
int len = in.readInt();
for(int i = 0; i< len; i++) {
MyPacket_subpckt sub = new MyPacket_subpckt();
sub.rawRead(in);
subpackets.add(sub);
}
}
}
MyPacket_subpckt implements java.io.Externalizable {
public int data; // etc
public void rawWrite(DataOutputStream out) {
out.write(data); // etc
}
public void rawRead(DataInputStream in) {
data = in.readInt(); // etc
}
}
You may find that the apporach above solves your problem. If you use vanilla
java serialization, your stream will have a bunch of other stuff (class
names etc) written to it. This may be blowing your packet size. If you
control the bytes like this, the problem may go away.
Otherwise, you can write the packet into a java.io.ByteArrayOutputStream.
This done, you can then use toByteArray() to get the serialised data as a
byte array, and send that byte array off to the remote port. You should then
be able to rawRead off the remote port .
class Utils {
public void sendAsSinglePacket(Raw pckt, Socket s) {
// you can do this, or you can keep a static buf and reset it before
each write
ByteArrayOutputStream buf = new ByteArrayOutputStream();
pckt.rawWrite(new DataOutputStream(buf));
s.getOutputStream().write(buf.toByteArray());
buf.close();
}
}
This should stuff the bytes representing your packet into a byte array, then
send the byte array as a single chunk.
Note that java strings are Unicode characters, which are witten in a
modified UTF-8 format specified in the docs for java.io.DataInputStream. If
you need strings transmitted as ascii bytes, then use
String.getBytes("US-ASCII") to get the string as a byte array, and new
String(byte[], "US-ASCII") to convert it back. Dont forget that you will
need to either add a count or null-terminate the string.
If it's *still* beaking up, you may want to look at
Socket.getSendBufferSize()
Let me know if it works. Cheers!
--------------------------------------------------------------
Repent! Quit your job! Slack off!
http://www.users.bigpond.com/pmurray
ICQ: 26066755
Technical Details
Message-ID:
<8y8I5.5998$e5.15517@newsfeeds.bigpond.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<39efb67d@news.iprimus.com.au>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 10d6db,597d7cc1e802e828 X-Google-Attributes: gid10d6db,public From: "Paul Murray" <pmurray@nospam.bigpond.com> Subject: Re: Java equivalent of C struct. Date: 2000/10/21 Message-ID: <8y8I5.5998$e5.15517@newsfeeds.bigpond.com> X-Deja-AN: 684040412 References: <39efb67d@news.iprimus.com.au> X-Priority: 3 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.3018.1300 X-Trace: newsfeeds.bigpond.com 972100868 139.134.123.46 (Sat, 21 Oct 2000 14:01:08 EST) Organization: Telstra BigPond Internet Services (http://www.bigpond.com) X-MSMail-Priority: Normal NNTP-Posting-Date: Sat, 21 Oct 2000 14:01:08 EST Newsgroups: aus.computers.java