Java 1.8
Eclipse
Java NIO的核心组件包含Channels,buffers,Selectors三个核心的组件,将Java NIO的网络编程模型总结如下图所示
构建网络应用服务端:EchoServer.javapackage hxb.echo;import java.io.IOException;import java.io.UnsupportedEncodingException;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.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;public class EchoServer { private Selector selector =null; public EchoServer(){ } /** * 写消息到客户端 */ private void doWrite(SocketChannel channel,String response) throws IOException{ byte[] bytes = response.getBytes(); ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length); writeBuffer.put(bytes); writeBuffer.flip(); channel.write(writeBuffer); } /** * 处理客户端信息 */ private void handleForReadKey(SelectionKey key) throws IOException, UnsupportedEncodingException { SocketChannel sc = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int readBytes = sc.read(buffer); if(readBytes>0){ buffer.flip(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); String msg = new String(bytes); System.out.println('Message send by Client:' + msg); //响应消息 String rspMsg = 'Send by Server:'+msg; doWrite(sc,rspMsg); } else if(readBytes<0){ key.cancel(); sc.close(); } } /** * 启动服务器 * @param port 服务器端口 */ public void start(int port) { ServerSocketChannel serverChannel = null; try { selector = Selector.open(); serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false);//配置为非阻塞模式 SocketAddress addr = new InetSocketAddress(port); serverChannel.bind(addr ); System.out.println('Start Echo server and listen on the port '+port); //监听 serverChannel.register(selector, SelectionKey.OP_ACCEPT); while(true) { //必须:唤醒selector selector.select(); Set
构建网络服务客户端处理线程:ClientHandle.javapackage hxb.echo;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;public class ClientHandle implements Runnable{ private String host; private int port; private Selector selector; private SocketChannel socketChannel; private volatile boolean started; public ClientHandle(String ip,int port) { this.host = ip; this.port = port; try{ selector = Selector.open(); socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false);//开启非阻塞模式 started = true; }catch(IOException e){ e.printStackTrace(); System.exit(1); } } public void stop(){ started = false; } @Override public void run() { try{ doConnect(); }catch(IOException e){ e.printStackTrace(); System.exit(1); } while(started){ try{ selector.select(); Set
构建网络应用客户端主程序Client.javapackage hxb.echo;import java.util.Scanner;public class Client { private static String DEFAULT_HOST = '127.0.0.1'; private static int DEFAULT_PORT = 9527; private static ClientHandle clientHandle; public static synchronized void start(String ip,int port){ if(clientHandle!=null) clientHandle.stop(); clientHandle = new ClientHandle(ip,port); new Thread(clientHandle,'Server').start(); } //向服务器发送消息 public static boolean sendMsg(String msg) throws Exception{ clientHandle.sendMsg(msg); return true; } public static void main(String[] args){ Client client = new Client(); client.start(DEFAULT_HOST,DEFAULT_PORT); try { while(Client.sendMsg(new Scanner(System.in).nextLine())); } catch (Exception e) { e.printStackTrace(); } } }
启动EchServer程序,在控制台Console会输出“”Start Echo server and listen on the port 9527“”,表明服务启动成功
启动Client客户端程序进行测试