SelectionKey.OP_WRITE versus SocketChannel.write(ByteBuffer)

I'm writing a small Socket server using Non blocking approach based on the ractor design pattern.
Many samples use the OP_WRITE on the selection keys to know when the channel is ready to accept writes.
I use the SocketChannel.write(ByteBuffer) whenever I need to write instead.
Is there a reason why SelectionKey.OP_WRITE is prefered in the samples??????
Thanks
Stéphane

Rainman4500 wrote:
I'm writing a small Socket server using Non blocking approach based on the ractor design pattern.
Many samples use the OP_WRITE on the selection keys to know when the channel is ready to accept writes.
I use the SocketChannel.write(ByteBuffer) whenever I need to write instead.
Is there a reason why SelectionKey.OP_WRITE is prefered in the samples??????
So that you don't attempt a write unless the channel can accept some data from you. In your example, suppose you actually transfer 0 bytes because the output buffer is still full. What do you do then?

Similar Messages

  • Socketchannel  write(bytebuffer)

    I use nio socketchannel write(bytebuffer [])method.
    In my program,as following...
    buff.clear();
    sc.read(buff);
    buff.flip();
    sc.write();
    sc.close();//Ok,when this line is not been marked.
    In another program,
    msg(String s)
    buff.get(s.getBytes());
    buff.flip();
    sc.write(buff);//No close(),and problems come,in design,
    sc can not close()
    How to solve the problem?

    You didn't show any client-side code, did you? Are you using a selector? If so, it could be that your select logic is wrong, causing you to miss when the socket first becomes readable (happened to me, for instance).
    When you ctrl-c the server, a TCP FIN packet gets sent to the client - if you were blocked in a select on the client side, it'd break out - and since the data in the TCP receive queue would still be there to read, your application would be able to read it out before getting an EOF on the socket.
    --bruce                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Problems with SocketChannel.write(ByteBuffer buff).

    I am using the following version of JDK on Red Hat Linux
    java version "1.4.2_01"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_01-b06)
    Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)
    I am using SocketChannel's write method mentioned above to write data to the SocketChannel. When data is being written on the SocketChannel via this write method and the underlying socket is closed by the receiving endpoint, I expect this method to throw an exception. This method does not throw any exception and returns me 0 as the value of number of bytes written out.
    The way my code is written out, it ends up going in an infinite loop. Now, I can very well fix my code to not run in an infinite loop, but is anybody else seeing this? Is this a valid behavior? Am I doing something wrong?
    Following is the code snippet that writes data to the SocketChannel. Note that writeBuffer is an instance of ByteBuffer and sc is an instance of SocketChannel. Both these variables are member variables in my class:
    public void write(byte[] buff, int offset, int length)
        throws IOException
        int toBeWritten = 0;
        while (length > 0)
            int writeOffset = offset;
            toBeWritten = writeBuffer.remaining();
            if (toBeWritten >= length)
                // All the bytes that are scheduled to be written will be
                // written.
                toBeWritten = length;
                length = 0;
            else
                // Only some of the bytes that are scheduled to be written will
                // be written.
                length -= toBeWritten;
                offset += toBeWritten;
            writeBuffer.put(buff, writeOffset, toBeWritten);
            // toBeWritten is the number of bytes that need to be written out.
            while (writeBuffer.position() != 0)
                // position = toBeWritten.
                writeBuffer.flip();
                // position = 0, limit = toBeWritten.
                int wrote = sc.write(writeBuffer);
                // position = wrote, limit = toBeWritten.
                // Compact the write buffer. It is very much possible that all
                // the bytes have not yet been written out.
                writeBuffer.compact();
                // The data that was written out, is now removed from the write
                // buffer. position = toBeWritten - wrote, limit = capacit
    }Thanks in advance!!

    When ByteBuffer.write(...) return 0, it means this
    socket is closed gracefully by another peer. the
    socket is need to re-connect again.Oh.. I forgot to mention, I am using non blocking SocketChannel. As per the Java docs for write(ByteBuffer src) method in WritableByteChannel:
    "Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer."
    So, I cannot assume that if the write method returns 0, the socket is closed by another peer.

  • Does SocketChannel.write() block

    I have a server communicating with it's clients using NIO and therefore SocketChannel's. When data are send to clients, the method SocketChannel.write(ByteBuffer) are used. The question is then, does the execution time depend of SocketChannel.write() depend on the speed of the client to receive data? Does the the method block in any way, or does it just send what is possible and then returns?

    If you have the channel in blocking mode, it also depends on how fast the client is reading. If the client isn't reading at all, ultimately its receive buffer will fill up, then the sender's sending buffer will fill, and then the write will block waiting for space in the send buffer; once the client starts reading again, space will become available and the write can complete. That's not to say that every write waits for the completion of every prior read, it's a matter of buffering and windowing, and the effect is rather decoupled because of the presence of two intermediate buffers. However it certainly can occur.

  • SocketChannel.write() blocking application

    Greets,
    I'm developping a huge application and got a latency/block problem using the write(ByteBuffer) method on a Socket from a socketchannel connection.
    Running java 1.5 (diablo) on Freebsd 6 servers, 4Gb ram (2.2 allocated to jvm), with dual xeon dual-core (total 4 cores)
    Here is the application schema :
    - A thread accepting connexion on the socketchannel
    - A thread selecting keys with data to process, enqueuing it after some basic checks on a command FIFO
    - A thread getting commands from the FIFO and processing 'em, generating answers on 4 answer FIFOs
    - 4 threads (1 per FIFO) to get answers and send 'em back to the socket.
    The application usually runs with 4500-5000 simultaneous clients.
    My problem is that the only write() method sometimes takes over 20ms to write a message, with a length smaller than 50 bytes.
    As I got about 25000 answers to process each second, when some of 'em decide to be slow, the 4 threads runs slowly, and all the connected clients are suffering of that latency, for the few minutes needed to empty the FIFOs.
    Every client socket get about 5 answers per second.
    On about 1 hour running, there are about 3 'peaks' of slowness, that I cannot explain yet. That's why I'm in need of advices !
    I monitored the application when such case happens. TOP indicates 40% cpu idle, JVM memory got >500Mb free, network runs @ about 1.2Mbps, where maximal transfer rate is >20Mbps. netstat -m told me no erros, and a large amount of free buffers available.
    As the only slow process is the write() method that usually runs faster than 1ms each call, but in those case I got delays over 20ms.
    freebsd tcp default sendbuffer size is 64k, receive buffer is 32k
    Commands average received size is below 1k, Answers average sending size below 8k.
    This application is running live, and as I cannot emulate 5000+ connections with a similar beahviour to test withour being sure that won't crash all.
    What points could be responsible of such slow write() calls ? Seems it's not CPU, not RAM, not network itself...
    I suppose it's the network buffers that are causing problems. But I don't really know if I have to fit 'em to a lower size, fitting my requirements, or to a larger size, to be sure there won't be full buffers blocking all ?
    I need advices. Thanks for your ideas !
    Bill

    Hmm. So you're happy to lose data?
    A few comments:
    (a) SocketChannels are thread-safe. I don't think you need the synchronization at all, unless maybe multiple writing threads are possible. I would eliminate that possibility and the sync myself.
    (b) If you're getting write delays of 30ms occasionally, the sync must also take 30ms at the same points if it is doing anything at all, i.e. if the possibility of multiple writing threads does exist. So maybe it doesn't?
    (c) I would have a good look at this:
    http://forum.java.sun.com/thread.jspa?threadID=459338
    and specifically the part on how to manage a channel that presents write blocks, using OP_WRITE when it happens and turning it off when it doesn't.
    (d) You seem to be using one output buffer for all channels. You might be better off using a small one per channel. Then that way you don't clear, you just do put/flip/write/compact, and if the write returned 0 just post OP_WRITE for next time around the select loop. Then you won't lose any data at all, except to a client who really isn't reading: you can detect that situation by keeping track of the last successful write time to a channel, and when there is pending data and the last write is too long ago have a think about what the block means in terms of the application. Maybe you should just disconnect the client?
    (e) It would be interesting to know how many times the write loop looped when you get these large delays, and also what the data size was, and also to know that for the other cases to see if there is a difference.
    (f) Generally from a fairness point of view I prefer not to have write loops, just one attempt and if it returns even a short read I post OP_WRITE as above. Otherwise you're spending too long servicing one channel.
    You can contact me offline via http://www.telekinesis.com.au if you like.

  • SelectionKey.interestOps(SelectionKey.OP_WRITE) blocking issue.

    Hi all,
    I am writing the server code by using NIO package and currently I am facing the problem while writing the partial data on to channel based on write event.
    The following approach I using for sending the data.
    - Getting the data from database and writing continuously onto socketchannel.
    - And if data is wrtten partially then, I am setting interest option write value as selectionkey.interestOps(SelectionKey.OP_WRITE) and later based on the write event on Selector::select() function we are handling the remaining data.
    So, the problem is coming over here after setting the interestOps(), the control is not coming out from that function where I am setting interestOps.
    Its coming on block.
    Even I tried by calling Selector.wakeup() before setting the SelectionKey.interestOps(SelectionKey.OP_WRITE).
    So please provide me suggestion regarding this.

    I have tested my function say send_packet() by putting more debug statement and what I am observing that If I call interestOps() function inside the send_packet() then blocking is not happeing at the line of interestOps() function. The problem is coming, the control of send_packet() function is not coming back to previous function(Say any function from where I am calling send_packet()).
    Here, I am displaying the debug message before calling to return statement of send_packet() then we can see the debug message then also the control of send_packet is not coming back to previous function.
    Later, I removed the interestOps() function from send_packet() function and then I found that control of send_packet() function is coming back to calling function.

  • How to decide ByteBuffer size created for SocketChannel.read(ByteBuffer)

    Hi,
    Is there any way by which we can know the size of data ready to be read at the SocketChannel?
    When the "SelectionKey" is discovered to be "isReadable()" I would like to create the ByteBuffer of the required size and use it for the SocketChannel.read(ByteBuffer) method.
    Right now I have to statically fix the ByteBuffer size to some safe maximum limit for this "read" method, which somehow is not looking efficient technique to me.
    Thanks in advance
    Amit

    Java doesn't tell you how much data is pending, but allocating the ByteBuffer 'statically' in advance is a better technique anyway. ByteBuffers are potentially expensive to create so you should allocate them just once per channel. The size is generally 8k or above depending on how many clients you expect to service at the same time and the amount of memory you can spare per client and in total.

  • Exceptions not thrown on interrupted SocketChannel.write()

    I just noticed a behaviour of java.nio.channels.SocketChannel.write() that makes me wonder. If write() blocks(), and the channel is closed during this blocking by another thread, AsynchronousCloseException should be thrown.
    However, in most cases this does not happen in my little test app. If any part of the data passed to write() has already been written to TCP before the socket was closed, write() returns without exception.
    Similar behaviour is observed with intterupting. If the thread blocked in write() is interrupted by another thread, it returns immediately and has the interrupted Flag set, but in most cases no Exception is thrown.
    ClosedByInterruptException is only thrown if not any part of the data passed to write() has been passed to TCP.
    Is this a bug or a feature ?

    Yes, i'm pretty sure that it blocks. In my test, the server just accepts the connection and then goes to sleep for a looooong time. The client just connects, and sends 10Meg of fata in one write() call. If i do not interrupt the client, it blocks as long as the server sleeps. In this case, this is the client's stack while blocking:
    Thread [main] (Suspended)     
         FileDispatcher.write0(FileDescriptor, long, int) line: not available [native method]     
         SocketDispatcher.write(FileDescriptor, long, int) line: 29     
         IOUtil.writeFromNativeBuffer(FileDescriptor, ByteBuffer, long, NativeDispatcher, Object) line: 104     
         IOUtil.write(FileDescriptor, ByteBuffer, long, NativeDispatcher, Object) line: 75     
         SocketChannelImpl.write(ByteBuffer) line: 334     
         Channels.write(WritableByteChannel, ByteBuffer) line: 60     
         Channels.access$000(WritableByteChannel, ByteBuffer) line: 47     
         Channels$1.write(byte[], int, int) line: 134     
         Channels$1(OutputStream).write(byte[]) line: 58     
         SocketClient.main(String[]) line: 75     If i start another thread before calling write(), that closes the socket after 3 seconds, the following happens: The call of IOUtil.write() returns ( with a value n that i cannot see in the debugger ), This value n is tested inside SocketChannelImpl.write() via (n > 0 || (n == IOStatus.UNAVAILABLE), what return true. For that reason, AbstractInterruptibleChannel.end(boolean), does not throw an exception.
    Once the server wakes up later, it is able to read about 200K from the socket...
    I tried this on a linux system (kernel 2.6.17, glibc 2.4) with jdk 1.6.0_03. I'm now gonna try it under windows, hold on..
    Of course, if anybody is interested, i'll post the test proggy...

  • SocketChannel.write() on J2SDK1.4.2_04/Windows 2000

    Hello,
    I have a question regarding SocketChannel.write() (as I mentioned before, I am using J2SDK 1.4.2_04 on Win 2000 pro).
    I prepared a ByteBuffer with some binary data. When I invoke SocketChannel.write(), the other application receives the data only until the first null (byte = 0) character is found??? What am I doing wrong??
    Thanks.

    On the other side, I get the message
    Read: ZYKT
    (only the first 4 bytes of the message)
    I experimented adding more non-null characters and the
    result was
    Read: ZYKT08@AYes, but (again) what does the CODE look like? Maybe it's written incorrectly to stop when it gets a null byte. Or maybe it stuffs it into a C-style char array (which is null-terminated by convention) and just happens to print up to the null (as C-style char array functions are designed to do). Or, who knows? You're not showing what that client process looks like.

  • SocketChannel.write()

    I've written a non-blocking server and am trying to test it with a client that uses the traditional (blocking) I/O. The problem I'm running into is when the server tries to write data to the client, it seems to take an inordinate amount of time.
    Often times the SocketChannel.write() method will return zero and write nothing to the socket when it has a perfectly good ByteBuffer available to be written. The Javadoc for the SocketChannel.write() states this is normal:
    Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer.
    So I put the following statement in the code:
    while ((retVal = socketChannel.write(outputBuffer)) == 0);However, this is proving to be quite slow, sometimes taking over half a second to complete a write of around 1000 bytes.
    While this solution delivers all of the data, it is slow. Has anybody run into this, and if so, found a better solution?
    Thanks,
    Ken

    I feel compelled to reply to myself to keep this alive, so to add:
    It seems like the delays being experience here would not happen with blocking sockets and that this is a function of NIO. What I don't understand is why socket channel takes so long to know when it can write again. Waiting over half a second for one write of a 1000 byte message is not acceptable.
    Is it because I am not using a Selector? Would that tell me the channel is ready any faster? I wouldn't see why. Or is it because the client application is reading the data too slowly?
    Any help would be appreciated.
    Ken

  • BufferOverflowException at socketChannel.read(byteBuffer)

    Hi!
    How does such exception take place at reading SocketChannel to ByteBuffer?
    *** EXCEPTION *** java.nio.BufferOverflowException
           java.nio.HeapByteBuffer.put(HeapByteBuffer.java:190)
           sun.nio.ch.IOUtil.read(IOUtil.java:209)
           sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:236)JavaDoc clearly says read() respects buffer.remaining.
    And I have met the same situation with channel.write(byteBuffer) - with BufferUnderflowException.
    Absolutely confused... White is black...
    java -version
    java version "1.6.0_06"
    Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
    Java HotSpot(TM) 64-Bit Server VM (build 10.0-b22, mixed mode)

    ejp wrote:
    Are you flipping the ByteBuffer before writing/getting? and compacting it afterwards?I even clear it. At any case methods contract doesn't demand anything about destination buffer.
    While googling I have found such problem description but without any solving.
    I have (not clear yet) suspicion it is something with concurrency and is going to dig in at this direction.

  • SocketChannel.write() throws IOException instead of returning 0

    I would like your opinion.
    When a send buffer is full in the OS, should a channel's write()
    return 0, or throw an exception? If an exception, should it be the
    same exception (IOException) thrown when truly exceptional events
    happen (e.g, a connection drop)?
    On Win32, SocketChannel.write() internally calls WSASend(). When
    WSASend() returns WSAEWOULDBLOCK, write() throws IOException. I
    think it should return zero instead, or at least throw an exception
    that can be distinguished easily (by other than parsing the
    IOException.getMessage())
    Should I submit a bug?
    Thanks,
    Juan

    The java doc for write() says it should return zero. If you have a simple test case that demonstrates the behavior you describe and it is not already in the bug database, then yes. You should file the bug report.

  • NIO Echo Server SocketChannel.write() multiple times?

    Hello,
    I have found and experimented with two simple nio echo socket servers,
    one from hutchinson's book. The other has similar code:
         if (key.isWritable())
         SocketChannel client = (SocketChannel) key.channel();
         ByteBuffer output = (ByteBuffer) key.attachment();
         output.flip();
         client.write(output);
                         output.compact();
         }but in my client, I noticed that when I send something to the server,
    apart from echoing it back it also sends back about 90 empty
    strings, which fire in my client's onData() event.
    Is this normal or am I missing something?
    Message was edited by:
    Robse

    This code is correct, and it can't send empty strings. The error is elsewhere.

  • Can SocketChannel.write return -1 ?

    Hi,
    In the SSLEngine documentation sample code it mentions handling a -1 returned by Channel.write() if the channel is closed.
    This is the only place I've ever seen it mentioned, there's nothing in the javadoc, and I've never come across it in practice.
    Can anybody confirm that this is just a mistake - or is it something my code needs to handle ?
    regards
    Tony Seebregts

    I've just submitted this as a bug. It occurs twice in the sample: once in the I/O section and once in the shutdown section. The tests for num == -1 and the associated empty code block and comment should be deleted. The code seems to have been copied & pasted from the read() block, where a -1 return is indeed valid.
    Also in the shutdown section it incorrectly has
    while (myNetData().hasRemaining())which should be
    while (myNetData.hasRemaining())Also surely myNetData needs to be flipped before the write and compacted afterwards, which means that the test should really be not hasRemaining() but position() > 0. hasRemaining() would only work if the buffer was already flipped.

  • NIO problem: multiple write

    Hello.
    I am using a NIO server for my application with a pool of WorkingThreads to handle client requests.
    The read part seems to work fine (I am deregistering the OP_READ interest when I begin to read from the socketchannel and I register it back when I finish processing the data). This way I am able to process data coming in chunks down the stream.
    Now, the problem I have is with writing data back to the client. If I send the data with only 1 socketChannel.write(ByteBuffer) method the client gets it correctly. But if I try to write in a while() loop more messages it happens that the client receives the first chunk correctly but SOMETIMES it receives rubbish as the next chunks. My guess is that after the first write(), the server may send some zeros to the client just before the next chunk so the client interprets that as valid data.
    I have tried to unregister the key from writing (key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE))) immediatelly after I've done a write() and reregister it for writing just before I want to send the data but this didn't help. I'm sure this is solvable but I haven't met anywhere code that deals with writing more than 1 buffer (like writing a big file for example).
    Any help would be very much appreciated.
    Thank you.
    Bogdan

    Thank you for replying, ejp, but it seems that what you said is not quite true. Here is my send method:
    public void send(SelectionKey key) {
         try {
              if (sendMessages.size() != 0) {
                   String message = null;
                   while (sendMessages.size() > 0) {
                        synchronized (sendMessages) {
                             message = (String) sendMessages.removeFirst();
                        ByteBuffer theBuffer = ByteBuffer.wrap(message.getBytes());
                        theBuffer.put(message.getBytes());
                        theBuffer.flip();
                        ((SocketChannel) key.channel()).write(theBuffer);
                        theBuffer.flip();
                        log.debug("Sent message:" + decoder.decode(theBuffer));
              key.interestOps(key.interestOps() | SelectionKey.OP_READ);
              key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
         } catch (IOException e) {
              key.cancel();
    }I verify what I send by outputting with the line log.debug("Sent message:" + decoder.decode(theBuffer));The messages are strings which are being taken from a LinkedList. The chunks I'm sending are of size 4096 bytes.
    I forgot to mention that the client uses simple IO (blocking mode). In between the sendings from the server it receives zeros and considers them as part of the message.
    I am using Windows 2000 + JDK 1.4.2_01

Maybe you are looking for

  • Trying to add a sign in module, but I need a little code help.

    I am trying to add a sign in, but this is what happens to my page. http://www.blisssurfadventures.com/about.html?Preview=True When trying to add in module the page content box only allows me to see a part of my web page.

  • NB200 - Virtual screen resolution on Windows 7

    Quote: +The 10.1-inch glossy screen features a resolution of 1,024 x 600, and is bright and pleasant to use.+ +If you find that some programs have elements which appear off the screen, the graphics drivers support a virtual resolution up to 1,600 x 1

  • White screen, again and again

    Hello everybody ! A friend of mine lent me his MacBook Pro A1286 because he always has a white screen at startup. Actually, the computer starts with the wellknown sound, the the logo appears, with the circle. After a few time, the screen switches to

  • How can I get my accurate DOB on Your Account Page?

    On the Your Account page the year DOB stops in 1942. Why? Aren't those of us who are older allowed to have a Your Account page?

  • Where does my brush go?

    After using the brush tool for awhile the circle (or whatever shape I was using) disappears and is replaced with a small, hard to see cross hair.  I don't like this at all.  What did I do for this change to happen and how do I avoid it?