Non-blocking method for reading writing objects to sockets

Discussion in 'Java' started by Sameer, May 6, 2005.

  1. Sameer

    Sameer Guest

    The methods writeObject and readObject of socket class are blocking
    one. i.e. if we create a ObjectInputStream object using
    new ObjectInputStream(socket.getInputStream()), the methods blocks
    until it gets some stream stuff.
    What is the corresponding non-blocking mthod so as to include in
    non-blocking programming?
    Sameer, May 6, 2005
    1. Advertisements

  2. Technically there are not non blocking socket write methods in any
    language. There is either room enough in the socket write MCB to hold
    the data, allowing the method to return, or there is not enough room,
    and an error is returned to indicate a failure.

    Either increase your transmit buffer size, which I believe defaults to
    32kb, or find out why the data is not being transmitted to the network.
    If your Objects are larger then 32kb, increasing the transmit buffer
    is the answer. If your Objects are smaller than 32kb, then you most
    likely have other issues.

    Joseph Dionne, May 6, 2005
    1. Advertisements

  3. It sounds like you are unsatisfied with this aspect of the constructor's
    behavior: "A serialization stream header is read from the stream and
    verified. This constructor will block until the corresponding
    ObjectOutputStream has written and flushed the header." (API docs)
    ObjectInputStreams are incompatible with non-blocking programming, and
    indeed, there can be no general-purpose, non-blocking alternative for
    which the minimal unit of transfer is a whole object. This is because
    it is impossible ever to guarantee to read an arbitrary object without
    blocking. (Consider, for instance, one that is too large to fit in the
    socket's kernel-level I/O buffer.)

    The stream header check performed by ObjectInputStream's constructor
    could conceivably be pushed back to the first read, allowing the
    constructor to avoid blocking, but it wouldn't gain you much because the
    reads themselves cannot be nonblocking.
    John C. Bollinger, May 6, 2005
  4. Sameer

    Sameer Guest

    I have designed one chatting software using non-blocking features of
    In this project I transferred data using non-blocking methods of Buffer
    related classes.
    Now I decided to change the design of the projct and I like to send the
    data as objects over the network using readObject and writeObject
    methods of socket class.
    For this purpose, I have to create instances ObjectInputStream and
    As per our previous discussion on this group the constructors of these
    classes are BLOCKING methods.
    Then how to carry out this? Is there any alternative or I have to
    continue with blocking approach i.e. a multithreaded chatting server
    where each thread handles one connection?
    The code given under is not working...
    Please suggest some remedy.

    import java.nio.channels.*;;
    import java.util.*;

    public class PollingChatServer {
    private int port;

    private Vector sockets = new Vector();

    public PollingChatServer(int port) throws IOException {
    this.port = port;

    private void listen() {
    try {
    ServerSocketChannel ssc =;
    ssc.socket().bind(new InetSocketAddress(port));
    System.out.println("Listening on port " + port);
    while (true) {
    System.out.println("Looking for connections...");
    SocketChannel sc = ssc.accept();
    if (sc != null) {
    System.out.println("Connection from " + sc);
    for (Enumeration e = sockets.elements(); e.hasMoreElements();) {
    SocketChannel socch = null;
    try {
    socch = (SocketChannel) (e.nextElement());
    Socket soc = socch.socket();
    System.out.println("In for loop before creation of ois...");
    //a blocking method ois
    ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
    Message messageObject = (Message) ois.readObject();
    String str = messageObject.message;
    if (str.length() != 0) {
    System.out.println("Sending " + str);
    Message.BroadcastMessage(str, sockets);
    } catch (IOException ie) {
    System.out.println("Connection lost: " + socch);
    } catch (ClassNotFoundException cnfe) {
    try {
    } catch (InterruptedException ie) {
    } catch (IOException ie) {

    public static void main(String args[]) throws Exception {
    int port = 12769;
    new PollingChatServer(port);
    Sameer, May 7, 2005
  5. Sameer

    Esmond Pitt Guest

    Technically and more accurately, there *are indeed* non-blocking socket
    write methods in both C and Java. In non-blocking mode, a socket write
    will put as much as it can of the application data into the socket send
    buffer without blocking and return that count, which can be zero if
    there was no room. This is not an error condition.

    I don't know what is meant by 'MCB', it is not a term associated with
    The default is platform dependent. It is 8k on Windows which is not
    to which the answer can really only be that the client isn't reading
    fast enough, or at all.
    Esmond Pitt, May 7, 2005
  6. One can read a socket non blocked, using a single method call, receiving
    either data, or no data. But, one cannot code a single method call to
    write non blocked in a "fire and forget" manner. Even you acknowledge
    that write might fail to emit all the data one attempted to write. So,
    one always needs to put a loop around socket write methods, terminating
    only after all data has been emitted.

    That is why is said "technically". Conceptually, a non blocked socket
    read method is expected to do one of two things, return data, or
    indicate that no data is returned, while a socket write can have three
    states, all data written, some data written, no data written. Since
    "some data written" will a application error. I'm pretty sure no one
    desires half of the STREAM delivered to the remote client.
    Joseph Dionne, May 7, 2005
  7. Sameer

    Esmond Pitt Guest

    or some data. There is a third state.
    or when you have something better to do in non-blocking mode than wait
    for the client to empty his receive buffer. Also, at some point you want
    to decide that this is never going to happen and you prefer to give up.
    Nevertheless that is how both the non-blocking read and non-blocking
    write calls behave on a socket. There are three states in both, and
    technically your statement does not hold water.

    and BTW what exactly is a socket MCB?
    Esmond Pitt, May 8, 2005
  8. Only proxy like applications, providing connectivity between two end
    points, can truly read a socket STREAM without regard to message
    boundaries. At some point, even a socket read method requires a
    complete packet delivery.

    As you may or may not know, not knowing the level of expertise you bring
    to this discussion, socket stream of non ASCII STREAMS, use two to four
    bytes preceding the data allowing the received to know the message size
    and prepare applications to receive the data. Prior to threading
    support, a relatively new feature, applications ip applications were
    just state engines, with socket I/O just one state, using select() or
    poll() to monitor state. These functions measured the leading edge
    event of a socket STREAM, data has arrived. If one did not read all the
    data received, select() (always), and poll() (most implementations)
    would not signal the socket handle ready until more data arrives. This
    is a common error in socket I/O applications.

    My original point what that there exist no single socket interface
    method that removes the responsibility to manage the socket STREAMS like
    garbage collection has done for memory management. And, now we have
    learned, even garbage collectors do not completely remove the job of
    proper memory management, one can still obfuscate Object references in
    many ways that prevent Object memory reclamation.
    An MCB, or the memory control blocks defining the socket's mbufs within
    the ip stack application interface. It is a term I use, but is not part
    of any user level, or even stack level, data structures. I was
    incorrect to inject my nomenclature, but I have been working at low
    level IP for decades, developing many features for my old IPX used with
    such ease as Java's socket interfaces today.

    Has that answered your question?
    Joseph Dionne, May 8, 2005
  9. Sameer

    Esmond Pitt Guest

    I've only been doing sockets since BSD 4.1, about 1983-4, but if this is
    supposed to be a statement that is true of all non ASCII streams it just
    isn't. Some application protocols do it. Some application protocols e.g.
    XDR do something else. TCP doesn't do *anything* except put the required
    length field in the IP header. Quite a few application protocols don't
    prefix message lengths either: Telnet, FTP, and HTTP for starters.
    Well, I though your original point was 'Technically there are not non
    blocking socket write methods in any language. There is either room
    enough in the socket write MCB to hold the data, allowing the method to
    return, or there is not enough room, and an error is returned to
    indicate a failure.' There's now so much irrelevance being added such as
    lectures on threads and further incorrect claims that the orignal
    incorrect statement is being obscured, but it's still incorrect.
    Esmond Pitt, May 9, 2005
  10. And how are you able to access the length field from the IP header via a
    Well, sir, I question your
    Joseph Dionne, May 9, 2005
  11. Sameer

    Esmond Pitt Guest

    You can't, and I haven't stated otherwise.
    You question my what? Whatever this was going to be, I probably agree
    with what you are trying say about how to program TCP streams, but
    introducing all these inaccurate irrelevancies into the discussion isn't
    helpful and causes confusion to uninformed readers.
    Esmond Pitt, May 9, 2005
  12. My apologies, it was not my intention to send that message. Honoring
    your concern of "inaccurate irrelevancies," I will not post replies
    anymore, adding to the "confusion to uninformed readers."
    Joseph Dionne, May 9, 2005
  13. Maybe something like this:

    byte[] buffer = new byte[xxxx];
    (use NIO to non-blocking read whole stream and write it to buffer)
    ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
    ObjectInputStream ois = new ObjectInputStream(bais);

    Unfortunately you can call "new ObjectInputStream()" after you read whole
    data from socket.
    Marcin Grunwald, May 9, 2005
  14. OK, that sounds reasonable.
    Why? What is to be gained by doing this, especially when you already
    have a working program?
    And what you have apparently missed is that reading and writing objects
    are *necessarily* *also* blocking operations.
    My recommendation would be to forget about transferring objects, as I
    don't see anything to be gained by it in your application. A
    multithreaded server with blocking I/O is another alternative.
    Depending on the nature of the task, a multithreaded server with
    _nonblocking_ I/O is sometimes appropriate. That last is the only mode
    I see in which you could manage to combine object I/O via Java's built
    in mechanism with non-blocking I/O, but by the time you were done you'd
    have much more complicated code than necessary, yet little or no
    improvement over the blocking I/O scenario.
    I should say not. The only thing you do in a non-blocking manner is
    accept connections. Even that you do a bit strangely, allowing the loop
    to spin until it accepts the first connection. You then apparently
    expect every live connection to provide a Message at every iteration of
    the loop -- that's completely contrary to a non-blocking paradigm. I
    cannot say how non-blocking-ready Message.BroadcastMessage may be, but
    based on its apparent purpose, it doesn't appear to have any chance of a
    correctly non-blocking implementation. Oh, and you don't seem to
    provide any way to close a connection once it is opened.
    Learn how to correctly implement non-blocking I/O. You said you already
    had a program that successfully used it, but your code below makes me
    doubtful of that. Once you understand non-blocking I/O better,
    contemplate Object I/O until you understand why it is incompatible with
    non-blocking I/O (if you can't figure it out then go back to step 1).
    Finally, use your new knowledge to redesign your application.

    We're still here if you conceive specific questions along your path to
    enlightenment, but if you come back with code that doesn't use a
    Selector then I, for one, will not hear you.
    John C. Bollinger, May 9, 2005
  15. Sameer

    Sameer Guest

    Dear Sir,
    Thanks for responding to my post.
    Posted is the most-simplified version of my original program.
    My program is based on the source code for non-blocking chat server
    provided in Advanced NIO, Manning Publication by Gregory Travis.
    I have a working system. But in this system I have to do a lot of
    string manipulation for managing the chat system.
    I have to give code to each message send to client/server and then
    decode it to display it appropriately.
    If the message the wrapped in a object along with other relevant
    information as fields and then this object is send, then the code will
    be much simplified.
    It is not possible to do 'Object Sending + NIO functionality'
    It seems that you have lot of doubts about the source code provided. If
    you have some source code which explain efficient handling of NIO for
    chat related stuff, please provide it to me.
    Sameer, May 10, 2005
  16. Sameer

    Sameer Guest

    A lot of technical stuff here about my posting.

    Can anybody provide some simple working examples about 'Object Sending
    + NIO functionality' in a Chat Server application?
    Sameer, May 10, 2005
  17. Given the context of this thread, I'll take that as "It is not possible
    to send and receive Objects without blocking???"

    One last time: no, it is not possible.

    Fuller explanation:

    * Sending an object down a byte stream has two steps, (1) creating a
    byte sequence representing the Object and all the other Objects it
    refers to directly or indirectly, and (2) sending the bytes.
    ObjectOutputStream bundles all this up into its writeObject() method.

    * Receiving an object from a byte stream has two steps, (1) receiving
    all the bytes for the Object itself and for all the other objects it
    refers to directly or indirectly, and (2) assembling the objects.
    ObjectInputStream bundles all this up into its readObject() method.

    * It is a fundamental characteristic of nonblocking I/O that the number
    of bytes transferred in a single operation is unpredictable; to send
    some fixed number of bytes you need to queue them and repeatedly,
    whenever the output channel is ready to accept some, send as many as you
    can without blocking. To receive bytes you do much the opposite,
    reading as many bytes as are available whenever any are available, and
    buffering them or queuing them for further handling by the application.
    There is typically a delay between the time one non-blocking
    operation is dispatched and the time another one can be successfully
    performed (with more than zero bytes transferred). All of that
    (including both writing and reading for multiple channels) can be
    managed in a single thread if it is done correctly.

    It is possible to handle an object write without blocking by capturing
    the output to a buffer (possibly by using a ByteArrayOutputStream) and
    then enqueuing the contents of the buffer and sending them in a
    non-blocking manner as described above. This is broken with respect to
    preserving referential integrity across the network link (which requires
    use of a single, continuous stream of objects, whereas this scheme would
    need to use a separate stream for each top-level object), but it could
    conceivably serve your purpose.

    It is *not* possible to perform an object read across a network (or from
    disk) without the possibility of blocking. This is because you need to
    receive *all* the bytes of the object before you can reconstitute it.
    At a low level you could conceivably use non-blocking I/O to get the
    bytes, but the overall "read object" operation cannot ever be guaranteed
    to complete without blocking because you are never guaranteed to get all
    the bytes in one read. Depending on the number of bytes required and
    the size of the various buffers involved, it might not be possible to
    *ever* get all the bytes in one read. Note also that with that being
    the case, your server would need to be multithreaded in any case -- the
    (nonblocking) network I/O operations would need to run in their own thread.
    John C. Bollinger, May 10, 2005
  18. I am not familiar with the book, but the fact that a code appears in
    print does not ensure that it is correct or bug-free. Moreover, if your
    code does not exactly duplicate the published one then whether or not
    the original code is correct is moot.
    No doubt it works, at least inasmuch as you can tell in your testing and
    use of it. That does not necessarily imply that it is actually avoiding
    ever blocking on I/O, however, or that it is correctly using the
    non-blocking capabilities or other features of NIO correctly. The code
    you posted definitely is missing some of the *essentials* of correct
    non-blocking I/O.
    I'm not sure I understand. Are you talking about character encodings?
    And where are you worrying about displaying the data? Are you in
    control of the clients? If so, then simply ensure that the clients
    always use the same charset (as each other) for sending and receiving
    messages. UTF-8 (or possibly UTF-16) will handle any and all characters
    Java supports. The server then never needs to decode (or recode) the
    I suspect the code could be much simplified via other approaches as
    well. At some level, however, you have to recognize that a multi-user
    network service is complex, and there's only so much simplification that
    can be done.

    Transferring data in object form might indeed be a good approach, but
    you have to use standard, blocking I/O at the object level.
    I do not have such code (specifically for chat), though I have general
    experience with NIO, and more with the equivalent features of C/UNIX. I
    don't see any particular reason why your problem domain (chat service)
    is relevant to the general use of NIO features or, specifically,
    non-blocking I/O. The topic is sufficiently complex, however, that I am
    not inclined to prepare an example code for you. I, or others here,
    will likely be willing to critique *complete* codes.
    John C. Bollinger, May 10, 2005
  19. Sameer

    jmricker Guest

    I would like to somehow interject my question into this discussion. I
    also am writing a client/server using non blocking io. However I have
    set up a selector to select those clients with buffers ready to be
    read. Instead of using objects, I'm sending buffers of bytes. My
    buffers are set up as:

    [int id][int id2][int payload size][ payload of bytes of size
    length ]

    Now lets say my client has sent off two of these buffers as two
    seperate (blocking?) writes in the time it takes for my server to get
    around to readying from it. Are you saying that a blocking read will
    just get the first buffer?

    So far what I've been doing is this:

    When a client connects, register the channel with a reading selector
    with an object that wraps up a bytebuffer and does other administrative
    tasks like checking header completeness.

    When I select channels that I can read from, I read up to 512 bytes,
    and push it into the container attached to the channel. I then check it
    for completeness. If not, then I go off checking other channels, then
    come back to this one, read off another 512 bytes, etc. Once I have a
    complete header and payload, I pass it off the appropriate controller,
    reset the container, and continue on.

    I'm hoping to avoid the loop spending too much time reading in from one
    client. My concern here is here, how can I be sure where the end of
    the buffer is at? Lets say the client sends an incorrect payload size
    or a byte of the payload gets lost in the transmission. If I have two
    buffers sitting to be read, I could easily start reading bytes from the
    second buffer into the first buffer. Any thoughts on my process?

    jmricker, May 11, 2005
  20. No, I'm not saying that. A single blocking read will get some number of
    bytes, which may be anything from a single byte to the full contents of
    both buffers (subject to various constraints, such as hardware and O/S
    buffer sizes).
    That sounds like the right way to go about it, although you need to be
    prepared for the case where you get the end one block _plus_ part or all
    of another in the same read. If the client is sending data rapidly then
    this is not too unlikely to happen.
    TCP provides reliable transmission. It's not foolproof, but you don't
    generally have to worry about data being lost in transmission without
    the connection being broken altogether. (It would take a combination of
    errors that is so unlikely to occur that you might as well ignore the
    possibility.) Likewise accidental data corruption on the wire. On the
    other hand, you either have to trust the client or have some way to
    detect when it goes goofy. Your protocol does not seem to support the

    I don't think any of that has much to do with hanging while reading from
    any particular client. If a channel is ready to read then you can read
    some number of bytes from it without blocking -- that's what it means
    for the channel to be ready. You can use a blocking or nonblocking read
    in this case; it doesn't matter. The alternative is to assign a unique
    thread to each client, use blocking I/O, and get on with the rest of the
    application. There are a great many servers that take the latter approach.
    John C. Bollinger, May 11, 2005
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.