NIO sockets

Hello,
Im having difficulty understanding the WRITE issue of nio sockets. Ive read most of the nio-related posts on this forum but I still cant figure it out. Ive also looked at some examples by PkWooster but they seems really complicated.
I have a server which accepts connections and echos messages to all clients. Everything works fine except my client cannot write to the server. I know I need to switch back and forth between Op interests since they can block the cpu if set incorrectly but I dont really understand what to set when. Since my server seems to be working fine Ill post my Clients code:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.InetSocketAddress;
import java.util.*;
import java.nio.charset.*;
public class GameClient implements Runnable {
  Game game;
  SocketChannel sc;
  ByteBuffer buffer;
Selector selector;
ByteBuffer sendBuffer=null;
    String host = "192.168.1.102";
    int port = 8888;
private CharsetDecoder asciiDecoder;
private CharsetEncoder encoder;
private LinkedList sendQ = new LinkedList();
SelectionKey sk;
LinkedList invocations;
public GameClient (Game g) {
game = g;
    buffer = ByteBuffer.allocateDirect(1024);
          Charset charset = Charset.forName("ISO-8859-1");
          asciiDecoder = charset.newDecoder();
          encoder = charset.newEncoder();
game.CharMSGArrival("Starting...");  // transfers data to the game thread
public void run(){
try{
    // Create a nonblocking socket channel and connect to server.
    sc = SocketChannel.open();
    sc.configureBlocking(false);
game.CharMSGArrival("Connecting to server..."+"\n");
    InetSocketAddress addr = new InetSocketAddress(host, port);
    sc.connect(addr);    // Nonblocking
    while (!sc.finishConnect()) {
game.CharMSGArrival("I am waiting ..."+"\n" );
game.CharMSGArrival("Connection acqired"+ "\n" );
    // Send initial message to server.
    buffer.put((new Date().toString()+ "\n").getBytes());
    buffer.flip();
    sc.write(buffer);
    // Create a new selector for use.
    selector = Selector.open();
    // Register the socket channel with the selector.
    sk = sc.register(selector, SelectionKey.OP_READ);
    while (true) {
        //System.out.println("Listening for server on port " +
         //                   remotePort);
        // Monitor the registered channel.
        int n = selector.select();
        if (n == 0) {
            continue;   // Continue to loop if no I/O activity.
        // Get an iterator over the set of selected keys.
        Iterator it = selector.selectedKeys().iterator();
        // Look at each key in the selected set.
        while (it.hasNext()) {
            // Get key from the selected set.
            SelectionKey key = (SelectionKey) it.next();
            // Remove key from selected set.
            it.remove();
            // Get the socket channel from the key.
            SocketChannel keyChannel = (SocketChannel) key.channel();
            // Is there data to read on this channel?
            if (key.isReadable()) {
                replyServer(keyChannel);
            if (key.isWritable()) {
                doSend();
       } catch (IOException ioe) {
  private void replyServer(SocketChannel socketChannel)
                      throws IOException {
    // Read from server.
buffer.flip( );
    int count = socketChannel.read(buffer);
    if (count <= 0) {
        // Close channel on EOF or if there is no data,
        // which also invalidates the key.
        socketChannel.close();
        return;
buffer.flip( );
String str = asciiDecoder.decode(buffer).toString( );
     game.CharMSGArrival(str);
public void doSend(){
sk.interestOps(SelectionKey.OP_WRITE);     
if(sendBuffer != null)write(sendBuffer);
writeQueued();     
public void trySend(String text){ // this method is invoked when a send buttong is pressed in the 'game' thread
          sendQ.add(text);     // first put it on the queue
          writeQueued();          // write all we can from the queue
     private void writeQueued()
          while(sendQ.size() > 0)     // now process the queue
               String msg = (String)sendQ.remove(0);
               write(msg);     // write the string
private void write(String text)
          try
          ByteBuffer buf = encoder.encode(CharBuffer.wrap(text));
               write(buf);
          catch(Exception e){e.printStackTrace();}
         * write out a byte buffer
     private void write(ByteBuffer data)
          SocketChannel scc = (SocketChannel)sk.channel();
          if(scc.isOpen())
               int len=0;
               if(data.hasRemaining())
                    try{len = sc.write(data);}
                    catch(IOException e){e.printStackTrace(); //closeComplete();
               if(data.hasRemaining())     // write would have blocked
game.CharMSGArrival("write blocked"+"/n");
                    //writeReady = false;
     sk.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);     // select OP_WRITE
                    sendBuffer = data;          // save the partial buffer
               else {sendBuffer = null;
sk.interestOps(SelectionKey.OP_READ);     }
          else game.CharMSGArrival("write closed"+"/n");
}

public void doSend(){
sk.interestOps(SelectionKey.OP_WRITE);     
if(sendBuffer != null)write(sendBuffer);
writeQueued();     
}This method makes no sense. You only get into it if the key is writable, which means it is already registered for OP_WRITE, so why would you register it again?
Also you're frequently ignoring the result of many write calls, of which you have too many.
See the thread 'Taming the NIO circus': http://forum.java.sun.com/thread.jspa?threadID=459338,
ignoring all the contributions except those by pkwooster and me.
I'm not that crazy about Mina myself. It has its own buffer classes and it quietly uses threads, i.e. missing the entire point of NIO.

Similar Messages

  • NIO sockets - cant get it to block!

    Hi,
    I'm trying to use NIO sockets in a program which sends data to a socket on another machine. I want it to block so that it must wait for a response before it continues. However this doesnt happen! I used Ethereal to see the packets being sent and recieved and the socket clearly doesnt block. Am I correct in thinking that NIO sockets are configured to block by default? I even tried using the configureBlocking(true) method to make sure but it still didnt block. Can anyone shed some light onto why this could be happening? Has this happened to anyone else?
    Cheers

    thomfost wrote:
    I've tried using regular I/O but its a bit too slow for what I need, im trying to see if using NIO improves this.Well you can stop now because it won't. NIO, as mentioned, is non-blocking IO, so a thread that is titled "NIO sockets - cant get it to block!" is not ultra promising. More importantly NIO will not make your IO "faster" by some magic. That's not what it does. It helps you write programs that scale because you don't need to have a thread dedicated to every client who connects to your system.
    At any rate you have multiple mistakes here which suggest the other slowness problem you refer to is a logical problem in your code. So why don't you tell us about that instead?

  • ANOTHER Java NIO Socket Bug??

    I think I'm being really dense here but for the life of me, I can't get this code to work properly. I am trying to build a NIO socket server using JDK 1.4.1-b21. I know about how the selector OP_WRITE functionality has changed and that isn't my problem. My problem is that when I run this code:
    if (key.isAcceptable()) {
         System.out.println("accept at " + System.currentTimeMillis());
         socket = server.accept();
         socket.configureBlocking(false);
         socket.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    if (key.isWritable()) {
         SocketChannel client = (SocketChannel)key.channel();
         System.out.println("write at " + System.currentTimeMillis());
    if (key.isReadable()) {
         SocketChannel client = (SocketChannel)key.channel();
         readBuffer.clear();
         client.read(readBuffer);
         System.out.println("read at " + System.currentTimeMillis());
    }the isWritable if statement will always return (which is fine) and the isReadable if statement will NEVER return (which is most certainly NOT FINE!!). The readBuffer code is there just to clear out the read buffer so isReadable is only called once per data sent.
    This SEEMS to be a bug in how the selector works? I would expect to see isReadable return true whenever data is sent, but that is not the case. Now here is the real kicker ;) Go ahead and change this line:
    socket.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);to this:socket.register(selector, SelectionKey.OP_READ);And now it appears that isReadable is running as expected?! To let people run this code on their own, I have uploaded a copy of the entire java file here:
    http://www.electrotank.com/lab/personal/mike/NioTest.java
    Please forgive the code, it's just the smallest test harness I could make and much of it is lifted from other posts on this forum. You can test this by using Telnet and connecting to 127.0.0.1:8080. You can test the isReadable piece by just typing in the Telnet window.
    Someone else has listed something as a bug in the Bug Parade, but the test case is flawed:
    http://developer.java.sun.com/developer/bugParade/bugs/4755720.html
    If this does prove to be a bug, has someone listed this already? Is there a nice clean workaround? I'm getting really desperate here. This bug makes the NIO socket stuff pretty unusable. Thanks in advance for the help!!
    Mike Grundvig
    [email protected]
    Electrotank, Inc.

    Yeah, isReadable crashed for me too.
    My solution was to not call it. I set up two selectors for the two operations I wanted notifying (accept and read) and used them independently in different threads. The accept thread passes them over to the read thread when they're accepted.
    This way I don't need to call isReadable since it is bound to be readable otherwise it wouldn't have returned, as read is the only operation I'm being notified about.
    --sam                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Wierdness with NIO socket on Solaris 2.10 part I

    i tried the following NioClient and MockServer, and saw some weird behavior.
    1. If i run both the client and server on the same machine on Windows, the client connects to the server, queries the instrument and gets the list of instruments back.
    2. if i run both client and server on the same Solaris 2.10 box, the NioClient doesn't get anything back from the MockServer, not even an ACCEPT
    3. if i run the client and the server on different solaris 2.10 machines, they work fine.
    have anyone seen this before? can sometone sheds some lights?
    import java.net.*;
    import java.io.*;
    public class MockServer
         public static int counter = 2;
        public static void main(String[] args) throws IOException {
             int portNumber = Integer.parseInt(args[0]);
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(portNumber);
            } catch (IOException e) {
                System.err.println("Could not listen on port: " + portNumber);
                System.exit(1);
             System.out.println ("Listening on socket " + portNumber);
            do {             
                 Socket clientSocket = null;
                 try {
                     clientSocket = serverSocket.accept();
                     System.out.println ("starting a new client....");
                     MyThread mt = new MyThread (clientSocket);
                     mt.run ();
                 } catch (IOException e) {
                     System.err.println("Accept failed.");
                     System.exit(1);
            while (true);
    class MyThread
         private final Socket clientSocket;
         MyThread (Socket clientSocket)
              this.clientSocket = clientSocket;
         public void run ()
            new Thread (new Runnable () {
                     public void run ()
                          try
                               boolean instrumentquery = false;
                               PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                               BufferedReader in = new BufferedReader(
                                           new InputStreamReader(
                                           clientSocket.getInputStream()));
                               String inputLine;                          
                               String successoutputLine =
                                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><return><returncode>success</returncode><detail>everything is good</detail></return>";
                               String failoutputLine =
                                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><return><returncode>failure</returncode><detail>something is not good</detail></return>";
                               String instrumentsoutput =
                                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><instruments><instrument><contract>usg-505Y</contract><cusip>12131121</cusip><deactivated>false</deactivated><halted>false</halted></instrument><instrument><contract>usg-305Y</contract><cusip>121312342</cusip><deactivated>false</deactivated><halted>false</halted></instrument></instruments>";
                               while ((inputLine = in.readLine()) != null) {
                                    System.out.println ("Receiving the following" + inputLine);
                                    if (inputLine.contains("queryInstrument")) instrumentquery = true;
                                    if (inputLine.contains("</a>"))
                                         if (instrumentquery)
                                              instrumentquery = false;
                                              System.out.println ("Sending " + instrumentsoutput);
                                              out.println (instrumentsoutput);
                                         else
                                              if ((MockServer.counter % 2) == 0)
                                                   System.out.println ("Sending " + successoutputLine);
                                                   out.println(successoutputLine);
                                              else
                                                   System.out.println ("Sending " + failoutputLine);
                                                   out.println(failoutputLine);
                                              MockServer.counter++;
                               out.close();
                               in.close();
                               clientSocket.close();}
                          catch (Exception ex)
                 }).start (); }
    }please see topic "wierdness with NIO socket on Solaris 2.10 part II" for the NioClient code as the maximum per topic is 5000.

    code for NioClient.java
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.nio.channels.spi.SelectorProvider;
    import java.util.*;
    public class NioClient implements Runnable {
    private InetAddress hostAddress;
    private int port;
    private Selector selector;
    private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
    private List pendingChanges = new LinkedList();
    private Map pendingData = new HashMap();
    private Map rspHandlers = Collections.synchronizedMap(new HashMap());
    public NioClient(InetAddress hostAddress, int port) throws IOException {
    this.hostAddress = hostAddress;
    this.port = port;
    this.selector = this.initSelector();
    public void send(byte[] data, RspHandler handler) throws IOException {
    SocketChannel socket = this.initiateConnection();
    this.rspHandlers.put(socket, handler);
    synchronized (this.pendingData) {
    List queue = (List) this.pendingData.get(socket);
    if (queue == null) {
    queue = new ArrayList();
    this.pendingData.put(socket, queue);
    queue.add(ByteBuffer.wrap(data));
    this.selector.wakeup();
    public void run() {
    while (true) {
    try {
    synchronized (this.pendingChanges) {
    Iterator changes = this.pendingChanges.iterator();
    while (changes.hasNext()) {
    ChangeRequest change = (ChangeRequest) changes.next();
    switch (change.type) {
    case ChangeRequest.CHANGEOPS:
    SelectionKey key = change.socket
    .keyFor(this.selector);
    key.interestOps(change.ops);
    break;
    case ChangeRequest.REGISTER:
    change.socket.register(this.selector, change.ops);
    break;
    this.pendingChanges.clear();
    this.selector.select();
    Iterator selectedKeys = this.selector.selectedKeys().iterator();
    while (selectedKeys.hasNext()) {
    SelectionKey key = (SelectionKey) selectedKeys.next();
    selectedKeys.remove();
    if (!key.isValid()) {
    continue;
    if (key.isConnectable()) {
    this.finishConnection(key);
    } else if (key.isReadable()) {
    this.read(key);
    } else if (key.isWritable()) {
    this.write(key);
    } catch (Exception e) {
    e.printStackTrace();
    private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    this.readBuffer.clear();
    int numRead;
    try {
    numRead = socketChannel.read(this.readBuffer);
    } catch (IOException e) {
    key.cancel();
    socketChannel.close();
    return;
    if (numRead == -1) {
    key.channel().close();
    key.cancel();
    return;
    this.handleResponse(socketChannel, this.readBuffer.array(), numRead);
    private void handleResponse(SocketChannel socketChannel, byte[] data,
    int numRead) throws IOException {
    byte[] rspData = new byte[numRead];
    System.arraycopy(data, 0, rspData, 0, numRead);
    RspHandler handler = (RspHandler) this.rspHandlers.get(socketChannel);
    if (handler.handleResponse(rspData)) {
    socketChannel.close();
    socketChannel.keyFor(this.selector).cancel();
    private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    synchronized (this.pendingData) {
    List queue = (List) this.pendingData.get(socketChannel);
    while (!queue.isEmpty()) {
    ByteBuffer buf = (ByteBuffer) queue.get(0);
    socketChannel.write(buf);
    if (buf.remaining() > 0) {
    break;
    queue.remove(0);
    if (queue.isEmpty()) {
    key.interestOps(SelectionKey.OP_READ);
    private void finishConnection(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    try {
    socketChannel.finishConnect();
    } catch (IOException e) {
    System.out.println(e);
    key.cancel();
    return;
    key.interestOps(SelectionKey.OP_WRITE);
    private SocketChannel initiateConnection() throws IOException {
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(false);
    socketChannel
    .connect(new InetSocketAddress(this.hostAddress, this.port));
    synchronized (this.pendingChanges) {
    this.pendingChanges.add(new ChangeRequest(socketChannel,
    ChangeRequest.REGISTER, SelectionKey.OP_CONNECT));
    return socketChannel;
    private Selector initSelector() throws IOException {
    return SelectorProvider.provider().openSelector();
    public static void main(String[] args) {
    try {
    System.out.println ("the host name is " + args[0]);
    NioClient client = new NioClient(
    InetAddress.getByName(args[0]), 4444);
    Thread t = new Thread(client);
    t.setDaemon(true);
    t.start();
    RspHandler handler = new RspHandler();
    client.send(
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><queryInstrument/></a>\n"
    .getBytes(), handler);
    handler.waitForResponse();
    } catch (Exception e) {
    e.printStackTrace();
    }

  • NIO Socket implementation - delay between select and get data from socket

    Hi all,
    I have implemented a internal CallAPI for RPC over a socket connection. It works fine but if there are more than five clients and some load I have the phenomena that the READ selector returns a SelectorKey but I did not get any data from the socket.
    My implementation is based on NIO has following components:
    + Accept-Thread
    Thread handles new clients.
    + Read-Thread
    Thread handles the data from the socket for the registered client. Each request is handled in an own Process-Thread. A Thread-Pool implementation is used for processing.
    + Process-Thread
    The Process-Thread reads the data from the socket and starts the processing of the logical request.
    In my tests I get the notification of data at the socket. The Process-Thread want to read the data for the socket, but no data are available. In some situations if have to read about 20 times and more to get the data. Between each read attempt I have inserted a sleep in the Process-Thread if no data was available. This have improved the problem, but it already exists. I tested the problem with several systems and jvm's but it seams that it is independent from the system.
    What can I to do improve the situation?
    I already include the read implementation from the grizzly-Framework. But it doesn't improve the situation.
    Socket - Init
         protected void openSocket( String host, int port ) throws IOException
              serverChannel = ServerSocketChannel.open();
              serverChannel.configureBlocking( false );
              serverSocket = serverChannel.socket();
              serverSocket.setReuseAddress( true );
              this.serverhost = host;
              this.serverport = port;
              this.srvAcceptSelector = Selector.open();
              this.srvReadSelector = Selector.open();
              InetSocketAddress isa = null;
              if ( serverhost != null )
                   isa = new InetSocketAddress( this.serverhost, this.serverport );
              else
                   isa = new InetSocketAddress( this.serverport );
              serverSocket.bind( isa, 50 );
              serverChannel.register( this.srvAcceptSelector, SelectionKey.OP_ACCEPT );
         }New Client � Init
         // New Client
         if ( key.isAcceptable())
              keyCountConnect++;
              ServerSocketChannel actChannel =
                   (ServerSocketChannel) key.channel();
              // Socket akteptieren
              SocketChannel actSocket = actChannel.accept();
              if ( actSocket != null )
                   actSocket.finishConnect();
                   actSocket.configureBlocking( false );
                   actSocket.socket().setTcpNoDelay( true );
                   this.registerSocketList.add( actSocket );
                   this.srvReadSelector.wakeup();
         }Read Data from Socket
        protected int readDatafromSocket( ByteArrayOutputStream socketdata )
             throws IOException
             int readedChars = 0;
            int count = -1;
            Selector readSelector = null;
            SelectionKey tmpKey = null;
            if ( sc.isOpen())
                  ByteBuffer inputbuffer = null;
                 try
                      inputbuffer = bufferpool.getBuffer();
                      while (( count = sc.read( inputbuffer )) > 0 )
                           readedChars += count;
                          inputbuffer.flip();
                           byte[] tmparray=new byte[inputbuffer.remaining()];
                           inputbuffer.get( tmparray );
                           socketdata.write( tmparray );
                          inputbuffer.clear();
                      if ( count < 0 )
                           this.closeSocket();
                           if( readedChars == 0 )
                                readedChars = -1;
                           if ( log.isDebug())
                                  log.debug( "Socket is closed! " );
                      else if ( readedChars == 0 )
                           if ( log.isDebug())
                                  log.debug( "Reread with TmpSelector" );
                           // Glassfish/Grizzly-Implementation
                         readSelector = SelectorFactory.getSelector();
                         if ( readSelector == null )
                              return 0;
                          count = 1;
                          tmpKey = this.sc.register( readSelector, SelectionKey.OP_READ );
                         tmpKey.interestOps(
                              tmpKey.interestOps() | SelectionKey.OP_READ );
                         int code = readSelector.select( 500 );
                         tmpKey.interestOps(
                             tmpKey.interestOps() & ( ~SelectionKey.OP_READ ));
                         if ( code == 0 )
                             return 0;
                             // Return on the main Selector and try again.
                           while (( count = sc.read( inputbuffer )) > 0 )
                                readedChars += count;
                               inputbuffer.flip();
                                byte[] tmparray=new byte[inputbuffer.remaining()];
                                inputbuffer.get( tmparray );
                                socketdata.write( tmparray );
                               inputbuffer.clear();
                           if ( count < 0 )
                                this.closeSocket();
                                if( readedChars == 0 )
                                     readedChars =-1;
                           else if ( count == 0 )
                                  // No data
                 finally
                      if ( inputbuffer != null )
                           bufferpool.releaseBuffer( inputbuffer );
                           inputbuffer = null;
                      // Glassfish-Implementierung
                    if ( tmpKey != null )
                        tmpKey.cancel();
                    if ( readSelector != null)
                        // Bug 6403933
                         try
                            readSelector.selectNow();
                         catch (IOException ex)
                        SelectorFactory.returnSelector( readSelector );
            return readedChars;
        }Thanks for your time.

    I've commented on that blog before. It is rubbish:
    - what does 'overloading the main Selector' actually mean? if anything?
    - 'Although this not clearly stated inside the NIO API documentation': The API documentation doesn't say anything about which Selector you should register channels with. Why would it? Register it with any Selector you like ...
    - 'the cost of maintaining multiple Selectors can reduce scalability instead of improving it' Exactly. So what is the point again?
    - 'wrapping a ByteBuffer inside a ByteBufferInputStream:' Code is rubbish and redundant. java.nio.channels.Channels has methods for this.
    There is no a priori advantage to using multiple Selectors and threads unless you have multiple CPUs. And even then not much, as non-blocking reads and writes don't consume significant amounts of CPU. It's the processing of the data once you've got it that takes the CPU, and that should be done in a separate thread.
    So I would re-evaluate your strategy. I suspect you're getting the channel registered with more than one Selector at a time. Implement it the simple way first then see if you really have a problem with 'overloading the main Selector' ...

  • Working with NIO and non-NIO sockets

    Hello,
    Trying to write a network manager kind of program where the client initiates a number of connections to different servers. Need to manage these connections through the life time of the session ( time the client is connected to the server). The client connections originate from a single machine, the servers are geographically distributed and about 1 to 5 connections between each client and server.
    I have tried and example NIO client/server application and it works fine. I have tried the KnockKnock client/server example it works. But when I try to use the NIO client with the multithreaded knockknock server, the socket connection goes through okay. However the data written to socket channel on the client(NIO) side doesn't seem to reach the server(non-NIO). I can't change the servers since they already exist in the field. I am just trying to write the manager application to manage them.
    Basically I am trying to avoid writing a multithreaded socket connection management program.
    Thanks for any input.

    Not the greatest NIO code. The author seems unaware that closing a channel also cancels all its selection keys so he laboriously programs both operations every time he needs to close the channel. His discussion of OP_CONNECT makes little sense: the important point is that OP_CONNECT is only used in the connection phase and OP_WRITE is only used in the connected phase.
    His code registers the channel for OP_WRITE as soon as the connection completes, when there is no pending data to write. This will just cause the selector to spin uselessly doing nothing. The channel should be registered with zero interest-ops and OP_WRITE should be registered when there is something to write, i.e. during the send() operation; and it should be deregistered when the write has completed successfully and there is no more data to write.

  • Need help with java.nio.socket program.

    Can someone please help me here? I am trying to create a class that listens on a socket for an incoming connection, but I am getting the following error on compile:
    SocketIn.java:48: incompatible types
    found : java.nio.channels.SocketChannel
    required: java.net.Socket
    Socket requestSocket = requestChannel.accept();
    Here is my code:
    package NETC;
    import java.net.*;
    import java.util.*;
    import java.io.*;
    import java.nio.*;
    import java.nio.charset.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    public class SocketIn{
         // Buffer for any incoming data.
         private static ByteBuffer inBuffer = ByteBuffer.allocateDirect(1024);
         CharBuffer charBuffer = null;
         public SocketIn(int intPort)throws Exception{
              // Create a non-blocking server socket.
              ServerSocketChannel serverChannel = ServerSocketChannel.open();
              serverChannel.configureBlocking(false);
              // Use the host and port to bind the server socket.
              InetAddress inetAddress = InetAddress.getLocalHost();
              InetSocketAddress socketAddress = new InetSocketAddress(inetAddress, intPort);
              serverChannel.socket().bind(socketAddress);
              // The selector for incoming requests.
              Selector requestSelector = SelectorProvider.provider().openSelector();
              // Put the server socket on the selectors 'ready list'.
              serverChannel.register(requestSelector, SelectionKey.OP_ACCEPT);
              while(requestSelector.select() > 0){
                   System.out.println("Connection Accepted...");
                   // A request has been made and is ready for IO.
                   Set requestKeys = requestSelector.selectedKeys();
                   Iterator iterator = requestKeys.iterator();
                   while(iterator.hasNext()){
                        SelectionKey requestKey = (SelectionKey)iterator.next();
                        // Get the socket that's ready for IO.
                        ServerSocketChannel requestChannel = (ServerSocketChannel)requestKey.channel();
                        // This shouldn't block.
                        Socket requestSocket = requestChannel.accept();
                        inBuffer.clear();
                        requestSocket.read(inBuffer);                    
                        inBuffer.flip();
                        Charset charset = Charset.forName("ISO-8859-1");
                        CharsetDecoder decoder = charset.newDecoder();
                        charBuffer = decoder.decode(inBuffer);
                        iterator.remove();                    
    }

    Well its been about a month and a half so I guess you have your answer. In case you don't...
    // This shouldn't block.
    Socket requestSocket = requestChannel.accept();
    The problem is quite simple. The ServerSocketChannel.accept() returns a SocketChannel. (Channel -> Channel).
    You can get access to the socket using the SocketChannel.
    SocketChannel requestSocketChannel = requestChannel.accept();
    Socket requestSocket = requestSocketChannel.socket();
    But you don't need the socket to read and write.

  • NIO Socket Reading - Intermittent Latency in High-Speed Data Reading

    Our application is reading data very fast over TCP/IP sockets in Java. We are using the NIO library with a non-blocking Sockets and a Selector to indicate readiness to read. On average, the overall processing times for reading and handling the read data is sub-millisecond. However we frequently see spikes of 10-20 milliseconds. (running on Linux).
    Using tcpdump we can see the time difference between tcpdump's reading of 2 discreet messages, and compare that with our applications time. We see tcpdump seems to have no delay, whereas the application can show 20 milliseconds.
    We are pretty sure this is not GC, because the GC log shows virtually no Full GC, and in JDK 6 (from what I understand) the default GC is parallel, so it should not be pausing the application threads (unless doing Full GC).
    It looks almost as if there is some delay for Java's Selector.select(0) method to return the readiness to read, because at the TCP layer, the data is already available to be read (and tcpdump is reading it).

    Have you tried profiling your application to confirm that the wait is indeed in the Selector.select() method, as you think?
    PS: Selector.select(0) will not return immediately if no channels are selected as you may assume. select(0) is the same as a regular select(): it will block until at least 1 channel is selected.

  • Wierdness with NIO socket on Solaris 2.10 part I I

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.nio.channels.spi.SelectorProvider;
    import java.util.*;
    public class NioClient implements Runnable {
    private InetAddress hostAddress;
    private int port;
    private Selector selector;
    private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
    private List pendingChanges = new LinkedList();
    private Map pendingData = new HashMap();
    private Map rspHandlers = Collections.synchronizedMap(new HashMap());
    public NioClient(InetAddress hostAddress, int port) throws IOException {
    this.hostAddress = hostAddress;
    this.port = port;
    this.selector = this.initSelector();
    public void send(byte[] data, RspHandler handler) throws IOException {
    SocketChannel socket = this.initiateConnection();
    this.rspHandlers.put(socket, handler);
    synchronized (this.pendingData) {
    List queue = (List) this.pendingData.get(socket);
    if (queue == null) {
    queue = new ArrayList();
    this.pendingData.put(socket, queue);
    queue.add(ByteBuffer.wrap(data));
    this.selector.wakeup();
    public void run() {
    while (true) {
    try {
    synchronized (this.pendingChanges) {
    Iterator changes = this.pendingChanges.iterator();
    while (changes.hasNext()) {
    ChangeRequest change = (ChangeRequest) changes.next();
    switch (change.type) {
    case ChangeRequest.CHANGEOPS:
    SelectionKey key = change.socket
    .keyFor(this.selector);
    key.interestOps(change.ops);
    break;
    case ChangeRequest.REGISTER:
    change.socket.register(this.selector, change.ops);
    break;
    this.pendingChanges.clear();
    this.selector.select();
    Iterator selectedKeys = this.selector.selectedKeys().iterator();
    while (selectedKeys.hasNext()) {
    SelectionKey key = (SelectionKey) selectedKeys.next();
    selectedKeys.remove();
    if (!key.isValid()) {
    continue;
    if (key.isConnectable()) {
    this.finishConnection(key);
    } else if (key.isReadable()) {
    this.read(key);
    } else if (key.isWritable()) {
    this.write(key);
    } catch (Exception e) {
    e.printStackTrace();
    private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    this.readBuffer.clear();
    int numRead;
    try {
    numRead = socketChannel.read(this.readBuffer);
    } catch (IOException e) {
    key.cancel();
    socketChannel.close();
    return;
    if (numRead == -1) {
    key.channel().close();
    key.cancel();
    return;
    this.handleResponse(socketChannel, this.readBuffer.array(), numRead);
    private void handleResponse(SocketChannel socketChannel, byte[] data,
    int numRead) throws IOException {
    byte[] rspData = new byte[numRead];
    System.arraycopy(data, 0, rspData, 0, numRead);
    RspHandler handler = (RspHandler) this.rspHandlers.get(socketChannel);
    if (handler.handleResponse(rspData)) {
    socketChannel.close();
    socketChannel.keyFor(this.selector).cancel();
    private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    synchronized (this.pendingData) {
    List queue = (List) this.pendingData.get(socketChannel);
    while (!queue.isEmpty()) {
    ByteBuffer buf = (ByteBuffer) queue.get(0);
    socketChannel.write(buf);
    if (buf.remaining() > 0) {
    break;
    queue.remove(0);
    if (queue.isEmpty()) {
    key.interestOps(SelectionKey.OP_READ);
    private void finishConnection(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    try {
    socketChannel.finishConnect();
    } catch (IOException e) {
    System.out.println(e);
    key.cancel();
    return;
    key.interestOps(SelectionKey.OP_WRITE);
    private SocketChannel initiateConnection() throws IOException {
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(false);
    socketChannel
    .connect(new InetSocketAddress(this.hostAddress, this.port));
    synchronized (this.pendingChanges) {
    this.pendingChanges.add(new ChangeRequest(socketChannel,
    ChangeRequest.REGISTER, SelectionKey.OP_CONNECT));
    return socketChannel;
    private Selector initSelector() throws IOException {
    return SelectorProvider.provider().openSelector();
    public static void main(String[] args) {
    try {
    System.out.println ("the host name is " + args[0]);
    NioClient client = new NioClient(
    InetAddress.getByName(args[0]), 4444);
    Thread t = new Thread(client);
    t.setDaemon(true);
    t.start();
    RspHandler handler = new RspHandler();
    client.send(
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><queryInstrument/></a>\n"
    .getBytes(), handler);
    handler.waitForResponse();
    } catch (Exception e) {
    e.printStackTrace();
    }Edited by: LuriRon on Mar 16, 2009 10:42 AM

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.nio.channels.spi.SelectorProvider;
    import java.util.*;
    public class NioClient implements Runnable {
    private InetAddress hostAddress;
    private int port;
    private Selector selector;
    private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
    private List pendingChanges = new LinkedList();
    private Map pendingData = new HashMap();
    private Map rspHandlers = Collections.synchronizedMap(new HashMap());
    public NioClient(InetAddress hostAddress, int port) throws IOException {
    this.hostAddress = hostAddress;
    this.port = port;
    this.selector = this.initSelector();
    public void send(byte[] data, RspHandler handler) throws IOException {
    SocketChannel socket = this.initiateConnection();
    this.rspHandlers.put(socket, handler);
    synchronized (this.pendingData) {
    List queue = (List) this.pendingData.get(socket);
    if (queue == null) {
    queue = new ArrayList();
    this.pendingData.put(socket, queue);
    queue.add(ByteBuffer.wrap(data));
    this.selector.wakeup();
    public void run() {
    while (true) {
    try {
    synchronized (this.pendingChanges) {
    Iterator changes = this.pendingChanges.iterator();
    while (changes.hasNext()) {
    ChangeRequest change = (ChangeRequest) changes.next();
    switch (change.type) {
    case ChangeRequest.CHANGEOPS:
    SelectionKey key = change.socket
    .keyFor(this.selector);
    key.interestOps(change.ops);
    break;
    case ChangeRequest.REGISTER:
    change.socket.register(this.selector, change.ops);
    break;
    this.pendingChanges.clear();
    this.selector.select();
    Iterator selectedKeys = this.selector.selectedKeys().iterator();
    while (selectedKeys.hasNext()) {
    SelectionKey key = (SelectionKey) selectedKeys.next();
    selectedKeys.remove();
    if (!key.isValid()) {
    continue;
    if (key.isConnectable()) {
    this.finishConnection(key);
    } else if (key.isReadable()) {
    this.read(key);
    } else if (key.isWritable()) {
    this.write(key);
    } catch (Exception e) {
    e.printStackTrace();
    private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    this.readBuffer.clear();
    int numRead;
    try {
    numRead = socketChannel.read(this.readBuffer);
    } catch (IOException e) {
    key.cancel();
    socketChannel.close();
    return;
    if (numRead == -1) {
    key.channel().close();
    key.cancel();
    return;
    this.handleResponse(socketChannel, this.readBuffer.array(), numRead);
    private void handleResponse(SocketChannel socketChannel, byte[] data,
    int numRead) throws IOException {
    byte[] rspData = new byte[numRead];
    System.arraycopy(data, 0, rspData, 0, numRead);
    RspHandler handler = (RspHandler) this.rspHandlers.get(socketChannel);
    if (handler.handleResponse(rspData)) {
    socketChannel.close();
    socketChannel.keyFor(this.selector).cancel();
    private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    synchronized (this.pendingData) {
    List queue = (List) this.pendingData.get(socketChannel);
    while (!queue.isEmpty()) {
    ByteBuffer buf = (ByteBuffer) queue.get(0);
    socketChannel.write(buf);
    if (buf.remaining() > 0) {
    break;
    queue.remove(0);
    if (queue.isEmpty()) {
    key.interestOps(SelectionKey.OP_READ);
    private void finishConnection(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    try {
    socketChannel.finishConnect();
    } catch (IOException e) {
    System.out.println(e);
    key.cancel();
    return;
    key.interestOps(SelectionKey.OP_WRITE);
    private SocketChannel initiateConnection() throws IOException {
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(false);
    socketChannel
    .connect(new InetSocketAddress(this.hostAddress, this.port));
    synchronized (this.pendingChanges) {
    this.pendingChanges.add(new ChangeRequest(socketChannel,
    ChangeRequest.REGISTER, SelectionKey.OP_CONNECT));
    return socketChannel;
    private Selector initSelector() throws IOException {
    return SelectorProvider.provider().openSelector();
    public static void main(String[] args) {
    try {
    System.out.println ("the host name is " + args[0]);
    NioClient client = new NioClient(
    InetAddress.getByName(args[0]), 4444);
    Thread t = new Thread(client);
    t.setDaemon(true);
    t.start();
    RspHandler handler = new RspHandler();
    client.send(
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><queryInstrument/></a>\n"
    .getBytes(), handler);
    handler.waitForResponse();
    } catch (Exception e) {
    e.printStackTrace();
    }Edited by: LuriRon on Mar 16, 2009 10:42 AM

  • TIME_WAIT nio socket leaks

    Hi All,
    I've read many posting and sites regarding this problem, but still can't find a good solution. I really hope someone can help here.
    I have a fairly simple client server setup. When the client disconnects the socket is being left in TIME_WAIT beyond the 2MSL.
    TCP exchange goes something like this
    client server
    ----------------------- connect
    syn
    syn ack
    ack
    ----------------------- send message to server, send reply to client
    psh ack
    ack
    psh ack
    ack
    ----------------------- disconnect
    fin ack
    ack
    fin ack
    ack
    but then the socket on the client side is never closed, stays in TIME_WAIT until JVM termination. The exchange looks a bit different from what I expected from reading the rfc on tcp ip. Anything obviously wrong with the above?
    Cheers
    Peter
    JDK 1.5
    problem discovered under suse, currently debugging under osx

    There was a fd leak in early releases of JDK5 that arose with applications using the socket adaptor. This was fixed in 5.0u7 so if you are running an earlier update that this then it could be the problem you are seeing. You mention you are on SuSE then there is a second issue can arise if you have channel registered with a Selector and then Selector doesn't wakeup regularly. If the channels are closed (by invoking close, not by the remote peer) then the close will be delayed until the Selector wakes up. In a busy system this tends not to be noticed because you are continuously waking up for events but in an idle system it can be noticed. This problem is specific to the poll based Selector. If you are a 2.6 kernel and can use jdk6 then it uses the epoll facility which does not have this problem. If you can't move to jdk6 for some reason then you'll see in the 5.0 release notes there is a note explaining how to use the epoll facility.

  • Identifying and managing clients in nonblocking NIO socket programming

    Here's my beef. When I write a Server using a thread for every new connection that comes in, I can remember everything for each client in its respective thread. I can have a table entry in a MYSQL database for each client which each thread can look up by a remembered id. I can direct packets from a different application to a specific client by passing a message to the thread associated with the client. But, in this implementation, the client-server setup will need to have a master-slave relationship where one is always reading, and can talk on the network only in response.
    I like the NIO selector way of doing things, but I do not get a memory method to deal with specific clients. How do I, for example,
    direct packets to a specific client.?
    recognize incoming packet info and make sense of its context in relation to past messages to and from the same client?
    maintain one-to-one correspondence between a MYSQL database table entry and a specific client?
    Could somebody explain this to me how I can maintain a client environment, and a client state machine with memory?
    Thanks
    Anil

    cloud9ine wrote:
    Here's my beef. When I write a Server using a thread for every new connection that comes in, I can remember everything for each client in its respective thread. I can have a table entry in a MYSQL database for each client which each thread can look up by a remembered id. I can direct packets from a different application to a specific client by passing a message to the thread associated with the client. But, in this implementation, the client-server setup will need to have a master-slave relationship where one is always reading, and can talk on the network only in response.
    I like the NIO selector way of doing things, but I do not get a memory method to deal with specific clients. How do I, for example,
    direct packets to a specific client.?
    recognize incoming packet info and make sense of its context in relation to past messages to and from the same client?
    maintain one-to-one correspondence between a MYSQL database table entry and a specific client?
    Could somebody explain this to me how I can maintain a client environment, and a client state machine with memory?
    Thanks
    AnilYou will use select() and SelectionKey when you deal with NIO. The SelectionKey has an attach method that you can use to associate the client with something, e.g. a session. Your Session class can contain all that you now have in your thread.
    Kaj

  • Socket NIO Problems

    I think I'm being really dense here but for the life of me, I can't get this code to work properly. I am trying to build a NIO socket server using JDK 1.4.1-b21. I know about how the selector OP_WRITE functionality has changed and that isn't my problem. My problem is that when I run this code:
    if (key.isAcceptable()) {
         System.out.println("accept at " + System.currentTimeMillis());     
         socket = server.accept();     
         socket.configureBlocking(false);     
         socket.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    if (key.isWritable()) {     
         System.out.println("write at " + System.currentTimeMillis());
    if (key.isReadable()) {     
         SocketChannel client = (SocketChannel)key.channel();     
         readBuffer.clear();     
         client.read(readBuffer);     
         System.out.println("read at " + System.currentTimeMillis());
    }the isWritable if statement will always return (which is fine) and the isReadable if statement will NEVER return (which is most certainly NOT FINE!!). The readBuffer code is there just to clear out the read buffer so isReadable is only called once per data sent.
    This SEEMS to be a bug in how the selector works? I would expect to see isReadable return true whenever data is sent, but that is not the case. Now here is the real kicker ;) Go ahead and change this line:socket.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);to this:socket.register(selector, SelectionKey.OP_READ);And now it appears that isReadable is running as expected?! To let people run this code on their own, I have uploaded a copy of the entire java file here:
    http://www.electrotank.com/lab/personal/mike/NioTest.java
    Please forgive the code, it's just the smallest test harness I could make and much of it is lifted from other posts on this forum. You can test this by using Telnet and connecting to 127.0.0.1:8080. You can test the isReadable piece by just typing in the Telnet window.
    Someone else has listed something as a bug in the Bug Parade, but the test case is flawed:
    http://developer.java.sun.com/developer/bugParade/bugs/4755720.html
    If this does prove to be a bug, has someone listed this already? Is there a nice clean workaround? I'm getting really desperate here. This bug makes the NIO socket stuff pretty unusable. Thanks in advance for the help!!
    Mike Grundvig
    [email protected]
    Electrotank, Inc.

    I'm not sure that a key will ever return with more than one operation bit selected. I expect that the selector simply puts the key into the selected set as soon as it sees any one of the interestedOps that match the current state.
    The general problem you are having, it seems, is that isWritable(), in many cases, will constantly return true for a low volume socket. This being the case, the only solution I see is to either deal with output with blocking calls or to dynamically change your interestedOps when there is data to write. That's what I did. I don't know yet how well it will scale. This is certainly not a bug, the application must deal with it. Perhaps it would be nice to have some kind of interface, like "SelectionKeyAttachment" and have the SelectionKey.attach() method take one of those. The SelectionKeyAttachment interface could implement something like isWritable(), isReadable(), isAcceptable() so that the Selector can also invoke the callback before putting it into the selected set. I haven't really thought this through, just initial thoughts.

  • About NIO non-blocking socket write method behavior

    Hi all -
    I hope anyone could help in this issue.
    Assume you create a NIO socket and configure its channel in non blocking mode:
    channel.configureBlocking(false);
    then you write a byte buffer into it:
    int sentBytesNum = channel.write(byteBuffer);
    What are the possibilities of sentBytesNum value? I am sure of two possibilities, which are:
    - all data sent so sentBytesNum equals byteBuffer data size (limit minus position before sending) (after sending the limit and position of byteBuffer are the same)
    - no data is sent so sentBytesNum is zero and byteBuffer limit and postion did not change, so we shall use a write selector to test when the channel will be ready for write to write the data.
    What I am not sure about and need someone to confirm is the third possibility:
    - only a part of data is sent (according to the available free space of socket output buffer) so sentBytesNum is more than zero but less than data size and byteBuffer position is advanced by the value of sentBytesNum, might this possibility happen??
    If yes, so we should manage to hold the non sent part of byteBuffer till the channel becomes ready for write (we can know that using write selector) so we can write it to channel???
    Thanks for help,
    Rocka

    Yes, case three can occur. The usual NIO write loop looks like this:
    int count = 0;
    while (buf.position() > 0)
      buf.flip();
      count = ch.write(buf);
      buf.compact();
      if (count == 0)
        break;
    }This will run until buf.position() == 0 or count == 0. If the partial write case happens it will loop one more time and probably get a 0 count.
    At the end of the loop, if buf.position() > 0 there is still unwritten data and at this point you should register for OP_WRITE and return to the selector. Otherwise if there is no data unwritten you should deregister OP_WRITE as you have nothing to write and aren't interested in the event any longer.
    If you are reading something and writing at the same time the logic goes like this:
    while (inch.read(buf) >= 0 || buf.position() > 0)
      // etc
    }This will read until EOF occurs and either buf.position() is zero or a zero length write occurred.

  • J2SE NIO vs J2EE

    We've created communication server using java nio socket where you can create clients of any language using socket to communicate to the server(java nio) application we made. The communication server can handle thousands of concurrent connected clients.
    My question is, is there a better way to create a communication server in J2EE that can handle thousands of concurrent connections?
    If there is, is there any advantage in doing so in terms of speed, scalability and functionality?
    Thanks in advance.

    georgemc is right. J2EE server can run on same JRE. However, some J2EE server will modifiy(or fine tune) the JRE for performance. Weblogic is one of the examples.
    I think a install package include everything may scare a beginner in Java. The J2EE server can increase the load of the OS.
    If you do not have the knowledge of J2EE, the error message of J2EE server(J2EE error+J2SE error) seems to be more difficult than the error come from J2SE.

  • Maximum number of concurrent connections using java sockets

    How can we find out the maximum number of concurrent connections that can be handled by a pooled connection server?
    I have a pooled server which creates a predefined number of handlers. Upon receiving a new request it accepts the connection and sends it to one of the handler.
    The solution works well for low number of concurrent connections - < 50 or 100
    But as the number increases there seems to be an issue
    1. Ignoring request even if i increase the handlers
    2. Increase in delay. [I feel that the listening thread is not getting the time slice to go read the socket for new requests]
    Any idea as to how i can solve this?
    Would an NIO socket help [am using the conventional java.io Serversocket, because my clients may not be non-blocking]??
    Any help would be appreciated.
    Anp

    There is no set maximum, but it is in the thousands on most platforms. I have a production server that handles tens of thousands of connections simultaneously. Most likely you have a bug in your code.

Maybe you are looking for

  • Delivery document no in shipment cube ?

    How to identify delivery document no from shipment extract stru ? I need a report with shipment details for specific del document no . Do v have any field in shipment extract structure where v can link it with delivery doc no . Let me know field name

  • Calculate Four Week Average SellThru In RPD

    Hello All, We have a requirement to calculate the four week average sellthru dynamically in OBIEE. Basically we need to expose SellThru Average as a column in presentation layer. The calculation of this column should use the below logic. Also see bel

  • I can't play CityVille on Firefox anymore. I have to go to IE to get CV. why?

    I've used Firefox for 2yrs and love it. I downloaded Norton yesterday and went to FB to play CV and the game would not load. After calling Norton, they downloaded IE as my browser and CV loaded. I DO NOT WANT IE as my browser. I restored it and nothi

  • Re: I am new here

    Hi I am also new here. I have a Toshiba Satellite model A205-S55805. Got it for my birthday. It was used, but looks good. Am having a problem with it shutting down while I am working. I have it plugged in so I know its not the battery. Anyone got any

  • Importing iPhoto Books into Aperture

    How do I get the books I've created in IPhoto into Aperture?