java 非阻塞 socket 编程

来自:http://www.exampledepot.com/egs/java.nio/pkg.html 

 // Creates a non-blocking socket channel for the specified host name and port.
    // connect() is called on the new channel before it is returned.
    public static SocketChannel createSocketChannel(String hostName, int port) throws IOException {
        // Create a non-blocking socket channel
        SocketChannel sChannel = SocketChannel.open();
        sChannel.configureBlocking(false);
    
        // Send a connection request to the server; this method is non-blocking
        sChannel.connect(new InetSocketAddress(hostName, port));
        return sChannel;
    }

    // Create a non-blocking socket and check for connections
    try {
        // Create a non-blocking socket channel on port 80
        SocketChannel sChannel = createSocketChannel("hostname.com", 80);
   
        // Before the socket is usable, the connection must be completed
        // by calling finishConnect(), which is non-blocking
        while (!sChannel.finishConnect()) {
            // Do something else
        }
        // Socket channel is now ready to use
    } catch (IOException e) {
    }


// Create a direct buffer to get bytes from socket.
    // Direct buffers should be long-lived and be reused as much as possible.
    ByteBuffer buf = ByteBuffer.allocateDirect(1024);
   
    try {
        // Clear the buffer and read bytes from socket
        buf.clear();
        int numBytesRead = socketChannel.read(buf);
   
        if (numBytesRead == -1) {
            // No more bytes can be read from the channel
            socketChannel.close();
        } else {
            // To read the bytes, flip the buffer
            buf.flip();
   
            // Read the bytes from the buffer ...;
            // see e159 Getting Bytes from a ByteBuffer
        }
    } catch (IOException e) {
        // Connection may have been closed
    }


// Create a direct buffer to get bytes from socket.
    // Direct buffers should be long-lived and be reused as much as possible.
    ByteBuffer buf = ByteBuffer.allocateDirect(1024);
   
    try {
        // Fill the buffer with the bytes to write;
        // see e160 Putting Bytes into a ByteBuffer
        buf.put((byte)0xFF);
   
        // Prepare the buffer for reading by the socket
        buf.flip();
   
        // Write bytes
        int numBytesWritten = socketChannel.write(buf);
    } catch (IOException e) {
        // Connection may have been closed
    }


// Create a selector and register two socket channels
    Selector selector = null;
    try {
        // Create the selector
        selector = Selector.open();
   
        // Create two non-blocking sockets. This method is implemented in
        // e173 Creating a Non-Blocking Socket.
        SocketChannel sChannel1 = createSocketChannel("hostname.com", 80);
        SocketChannel sChannel2 = createSocketChannel("hostname.com", 80);
   
        // Register the channel with selector, listening for all events
        sChannel1.register(selector, sChannel1.validOps());
        sChannel2.register(selector, sChannel1.validOps());
    } catch (IOException e) {
    }
   
    // Wait for events
    while (true) {
        try {
            // Wait for an event
            selector.select();
        } catch (IOException e) {
            // Handle error with selector
            break;
        }
   
        // Get list of selection keys with pending events
        Iterator it = selector.selectedKeys().iterator();
   
        // Process each key at a time
        while (it.hasNext()) {
            // Get the selection key
            SelectionKey selKey = (SelectionKey)it.next();
   
            // Remove it from the list to indicate that it is being processed
            it.remove();
   
            try {
                processSelectionKey(selKey);
            } catch (IOException e) {
                // Handle error with channel and unregister
                selKey.cancel();
            }
        }
    }
   
    public void processSelectionKey(SelectionKey selKey) throws IOException {
        // Since the ready operations are cumulative,
        // need to check readiness for each operation
        if (selKey.isValid() && selKey.isConnectable()) {
            // Get channel with connection request
            SocketChannel sChannel = (SocketChannel)selKey.channel();
   
            boolean success = sChannel.finishConnect();
            if (!success) {
                // An error occurred; handle it
   
                // Unregister the channel with this selector
                selKey.cancel();
            }
        }
        if (selKey.isValid() && selKey.isReadable()) {
            // Get channel with bytes to read
            SocketChannel sChannel = (SocketChannel)selKey.channel();
   
            // See e174 Reading from a SocketChannel
        }
        if (selKey.isValid() && selKey.isWritable()) {
            // Get channel that's ready for more bytes
            SocketChannel sChannel = (SocketChannel)selKey.channel();
   
            // See e175 Writing to a SocketChannel
        }
    }

// Create a non-blocking server socket and check for connections
    try {
        // Create a non-blocking server socket channel on port 80
        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        ssChannel.configureBlocking(false);
        int port = 80;
        ssChannel.socket().bind(new InetSocketAddress(port));
   
        // See e178 Accepting a Connection on a ServerSocketChannel
        // for an example of accepting a connection request
    } catch (IOException e) {
    }


// Get port that received the connection request; this information
    // might be useful in determining how to handle the connection
    int localPort = serverSocketChannel.socket().getLocalPort();
   
    try {
        // Accept the connection request.
        // If serverSocketChannel is blocking, this method blocks.
        // The returned channel is in blocking mode.
        SocketChannel sChannel = serverSocketChannel.accept();
   
        // If serverSocketChannel is non-blocking, sChannel may be null
        if (sChannel == null) {
            // There were no pending connection requests; try again later.
            // To be notified of connection requests,
            // see e179 Using a Selector to Manage Non-Blocking Server Sockets.
        } else {
            // Use the socket channel to communicate with the client
            // See e176 Using a Selector to Manage Non-Blocking Sockets.
        }
    } catch (IOException e) {
    }


try {
        // Create the selector
        Selector selector = Selector.open();
   
        // Create two non-blocking server sockets on 80 and 81
        ServerSocketChannel ssChannel1 = ServerSocketChannel.open();
        ssChannel1.configureBlocking(false);
        ssChannel1.socket().bind(new InetSocketAddress(80));
   
        ServerSocketChannel ssChannel2 = ServerSocketChannel.open();
        ssChannel2.configureBlocking(false);
        ssChannel2.socket().bind(new InetSocketAddress(81));
   
        // Register both channels with selector
        ssChannel1.register(selector, SelectionKey.OP_ACCEPT);
        ssChannel2.register(selector, SelectionKey.OP_ACCEPT);
   
        while (true) {
            // Wait for an event
            selector.select();
   
            // Get list of selection keys with pending events
            Iterator it = selector.selectedKeys().iterator();
   
            // Process each key
            while (it.hasNext()) {
                // Get the selection key
                SelectionKey selKey = (SelectionKey)it.next();
   
                // Remove it from the list to indicate that it is being processed
                it.remove();
   
                // Check if it's a connection request
                if (selKey.isAcceptable()) {
                    // Get channel with connection request
                    ServerSocketChannel ssChannel = (ServerSocketChannel)selKey.channel();
   
                    // See e178 Accepting a Connection on a ServerSocketChannel
                    // for an example of accepting a connection request
                }
            }
        }
    } catch (IOException e) {
    }


try {
        // Read from socket
        int numBytesRead = socketChannel.read(buf);
   
        if (numBytesRead == -1) {
            // No more bytes can be read from the channel
            socketChannel.close();
        } else {
            // Read the bytes from the buffer
        }
    } catch (IOException e) {
        // Connection may have been closed
    }
   
    try {
        // Write to socket
        int numBytesWritten = socketChannel.write(buf);
    } catch (IOException e) {
        // Connection may have been closed
    }

你可能感兴趣的:(java 非阻塞 socket 编程)