Hi Thomas,
I would suggest to read the header data as a chunk, to avoid implementing a
complex state machine. This can be done by using the read mark support. For
an example see the tutorial and the implementation of the ConectionUtils
method validateSufficientDatasizeByIntLengthField() (
http://xsocket.svn.sourceforge.net/viewvc/xsocket/xsocket/core/trunk/src/main/java/org/xsocket/connection/ConnectionUtils.java?view=markup
).
To read the content I would attach the content handler to the connection.
See below
Gregor
Example:
MyProtocolHandler implements IDataHandler {
public boolean onData(INonBlockingConnection connection) throws
IOException, BufferUnderflowException {
ContentHandler ch = (ContentHandler) connection.getAttachment();
// content handling mode?
if (ch != null) {
return ch.onData(connection);
}
// no -> read the header as chunk
connection.resetToReadMark(); // reset (if former reads has
been failed)
connection.markReadPosition();
// if not enough data is available a BufferUnderFlowException
will be thrown
String identifier = connection.readStringByDelimiter("\r\n");
String checksum = connection.readStringByDelimiter("\r\n");
String length = ...
connection.removeReadMark(); // all read!
ContentHandler ch = new ContentHandler(length, checksum)
connection.setAttachment(ch);
ch.onData(connection);
return true;
}
class ContentHandler implements IDataHandler {
private int remaining = 0;
private int checkSum = 0;
private ...
ContentHandler(int length,int checkSum, ...) {
this.remaining = length;
...
// create the inflator
...
}
public boolean onData(INonBlockingConnection connection) throws
IOException, BufferUnderflowException {
int available = connection.available();
int readSize = available;
if (available > remaining) {
readSize = reamaining
}
byte bytes = connection.readBytesByLength(readSize);
reamaining -= readSize;
// call inflator
...
if (remaining == 0) {
connection.setAttachment(null);
}
return true;
}
}
}
2008/2/17, Thomas Steinmaurer <ts...@ib...>:
>
> Hello,
>
> I'm in the process of writing a socket server which basically receives
> data according to a self-defined protocol from mobile devices. The data
> is a mix of line-oriented character data (terminated with a '\n') and
> some kind of payload, which is a ZLib compressed byte stream.
>
> E.g., the client sends the following data in the following sequence to
> the server.
>
> Identifier\n
> Checksum value\n
> Length of compressed payload\n
> ZLib compressed payload byte stream
>
> In a first step, I have written a multi-threaded socket server, which
> uses common IO classes like DataInputStream. Performance is ok on a
> local area network, but due to the blocking issue of any read method of
> a DataInputStream, performance is pretty bad, especially in a
> low-bandwith network.
>
> So I came across NIO and xSocket as one framework using Java NIO.
>
> How can I implement a socket server with xSocket which:
>
> * Implements the protocol as shown above (mix of line-oriented
> characters and a ZLib compressed byte stream)
> * Is non-blocking, so at least a few number of simultaneous clients are
> handled gracefully
> * Of course, each client needs to be isolated from each other
>
>
>
> Any hints, code snippets, ... are much appreciated.
>
>
> Thank you very much.
>
> Regards,
> Thomas
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> xSocket-develop mailing list
> xSo...@li...
> https://lists.sourceforge.net/lists/listinfo/xsocket-develop
>
|