From: https://www.iteye.com/blog/mars914-1238353
In java, TCP / IP + NIO inter-system communication can be realized based on the related classes of Channel and Selector in java.nio.channels.
Used for inter-system communication. SocketChannel and ServerSocketChannel are used. SocketChannel is used to establish connections, monitor events and read and write operations. ServerSocketChannel is used to monitor ports and monitor connection events. You can use the Selector to obtain whether there are events to be processed.
Server java code:
- package com.java.distributed.message.tcpip;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.ServerSocketChannel;
- import java.nio.channels.SocketChannel;
- import java.nio.charset.Charset;
- public class NIOServer {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- int port =7889;
- // Open the selector
- Selector selector=Selector.open();
- // Open the server socket channel
- ServerSocketChannel ssc=ServerSocketChannel.open();
- // Retrieve the server socket associated with this channel
- ServerSocket serverSocket=ssc.socket();
- // Bind ServerSocket to a specific address (IP address and port number)
- serverSocket.bind(new InetSocketAddress(port));
- System.out.println("server listen on port:"+port);
- // Adjust the blocking mode of the channel
- ssc.configureBlocking(false);
- // Register this channel with the given selector and return a selection key. SelectionKey.OP_ACCEPT--Operation set bit for socket accept operation
- ssc.register(selector, SelectionKey.OP_ACCEPT);
- while(true){
- // timeout: positive, then block at most timeout ms while waiting for a channel to be ready; if zero, block indefinitely; must be non-negative
- int nKeys=selector.select(1000);
- if(nKeys>0){
- for(SelectionKey key:selector.selectedKeys()){
- / * Test whether the channel of this key is ready to accept new socket connections--
- * If the channel of this key does not support socket accept operation, this method always returns false
- * */
- if(key.isAcceptable()){
- ServerSocketChannel server=(ServerSocketChannel) key.channel();
- SocketChannel sc=server.accept();
- if(sc==null){
- continue;
- }
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_READ);
- }else if(key.isReadable()){
- // Allocate a new byte buffer
- ByteBuffer buffer=ByteBuffer.allocate(1024);
- SocketChannel sc=(SocketChannel) key.channel();
- int readBytes=0;
- String message=null;
- try{
- int ret;
- try{
- while((ret=sc.read(buffer))>0){
- readBytes + = ret;
- }
- }catch(Exception e ){
- readBytes=0;
- //ignore
- }finally{
- // Reverse this buffer. First set a limit on the current position, then set the position to zero
- buffer.flip();
- }
- if(readBytes>0){
- message=Charset.forName("UTF-8").decode(buffer).toString();
- buffer=null;
- }
- }finally{
- if(buffer!=null)
- buffer.clear();
- }
- if(readBytes>0){
- System.out.println("message from client:"+message);
- if("quit".equalsIgnoreCase(message.trim())){
- sc.close();
- selector.close();
- System.out.println("Server has been shutdown!");
- System.exit(0);
- }
- String outMessage="server response:"+message;
- sc.write(Charset.forName("UTF-8").encode(outMessage));
- }
- }
- }
- selector.selectedKeys().clear();
- }
- }
- }
- }
Client java code:
- package com.java.distributed.message.tcpip;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.InetSocketAddress;
- import java.net.SocketAddress;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.SocketChannel;
- import java.nio.charset.Charset;
- public class NIOClient {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- int port =7889;
- SocketChannel channel=SocketChannel.open();
- channel.configureBlocking(false);
- SocketAddress target=new InetSocketAddress("127.0.0.1",port);
- channel.connect(target);
- Selector selector=Selector.open();
- // Operation set bit for socket connection operation
- channel.register(selector, SelectionKey.OP_CONNECT);
- BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));
- while(true){
- if(channel.isConnected()){
- String command=systemIn.readLine();
- channel.write(Charset.forName("UTF-8").encode(command));
- if(command==null||"quit".equalsIgnoreCase(command.trim())){
- systemIn.close();
- channel.close();
- selector.close();
- System.out.println("Client quit !");
- System.exit(0);
- }
- }
- int nKeys=selector.select(1000);
- if(nKeys>0){
- for(SelectionKey key:selector.selectedKeys()){
- if(key.isConnectable()){
- SocketChannel sc=(SocketChannel) key.channel();
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_READ);
- sc.finishConnect();
- }else if(key.isReadable()){
- ByteBuffer buffer=ByteBuffer.allocate(1024);
- SocketChannel sc=(SocketChannel) key.channel();
- int readBytes=0;
- try{
- int ret = 0;
- try{
- while((ret=sc.read(buffer))>0){
- read bytes = K +;
- }
- }finally{
- buffer.flip();
- }
- if (readBytes > 0) {
- System.out.println(Charset.forName("UTF-8")
- .decode(buffer).toString());
- buffer = null;
- }
- }finally {
- if (buffer != null) {
- buffer.clear();
- }
- }
- }
- }
- selector.selectedKeys().clear();
- }
- }
- }
- }