本文共 6396 字,大约阅读时间需要 21 分钟。
1.IO的基本操作
只线程情况下只能有一个客户端的连接
package xss.netty.basicio;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;/** * java 原生的IO处理方式 * IO Server */public class IOMainServerTest { public static void main(String[] args) throws Exception { ServerSocket serverSocket=new ServerSocket(9999); System.out.println("server start......."); while (true){ // 会阻塞client的连接,只到client的消息处理完 //也就是说一次只能处理一个客户端的请求 Socket socket=serverSocket.accept(); System.out.println("new client connect"); handler(socket); } } public static void handler(Socket socket) { try{ InputStream inputStream=socket.getInputStream(); byte[] readBytes=new byte[1024]; while(true){ int reads =inputStream.read(readBytes);//阻塞数据的读取 if(reads != -1){ System.out.println("message ->"+new String(readBytes,0,reads)); }else{ break; } } }catch (Exception ex){ ex.printStackTrace(); }finally { try { System.out.println("socket closed."); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }}
可多客户端的同时连接
package xss.netty.basicio;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * java 原生的IO处理方式 * 改进之一:服务端可以同时接收多个客户端的请求 * */public class IOMainServerMutliClientTest { public static void main(String[] args) throws Exception { ServerSocket serverSocket=new ServerSocket(9999); System.out.println("server start......."); ExecutorService executors= Executors.newCachedThreadPool(); while (true){ // 会阻塞client的连接,只到client的消息处理完 //也就是说一次只能处理一个客户端的请求 final Socket socket=serverSocket.accept(); System.out.println("new client connect"); executors.execute(new Runnable() { public void run() { handler(socket); } }); } } public static void handler(Socket socket) { try{ InputStream inputStream=socket.getInputStream(); byte[] readBytes=new byte[1024]; while(true){ int reads =inputStream.read(readBytes);//阻塞数据的读取 if(reads != -1){ System.out.println("message ->"+new String(readBytes,0,reads)); }else{ break; } } }catch (Exception ex){ ex.printStackTrace(); }finally { try { System.out.println("socket closed."); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }}
2.NIO的基本操作
package xss.netty.basicio;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.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;/** * NIO 基本知识点 */public class NIOMainServerTest { //通道的管理,监听客户发送的事件 private Selector selector; public static void main(String[] args) throws Exception{ NIOMainServerTest serverTest=new NIOMainServerTest(); serverTest.initServer(9999); serverTest.listen(); System.out.println("main executed."); } /** * 初始化ServerSocket 通道 * @param port * @throws IOException */ public void initServer(int port) throws IOException{ ServerSocketChannel serverSocketChannel=ServerSocketChannel.open(); //设置为非阻塞通道 serverSocketChannel.configureBlocking(false); //绑定端口 serverSocketChannel.socket().bind(new InetSocketAddress(port)); // this.selector=Selector.open(); //将selector 与 通道进行绑定,并且注册ACCEPT事件 //selector会阻塞监听是否有ACCEPT事件的到达。Selector.select() serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT); System.out.println("Server init finished with prot="+port); } /** * 轮询监听selector上是否有需要处理的事件 * @throws IOException */ public void listen() throws IOException{ System.out.println("start listen..."); while (true){ //当注册的事件到达时,方法返回;否则,该方法会一直阻塞 selector.select(); //获得selector中选中的项的迭代器,选中的项为注册的事件 Iterator iterator=this.selector.selectedKeys().iterator(); while(iterator.hasNext()){ SelectionKey selectionKey=(SelectionKey)iterator.next(); iterator.remove();//删除已选的key,以防重复处理 //处理请求 this.handler(selectionKey); } } } /** * 事件类型请求的处理 * @param key * @throws IOException */ public void handler(SelectionKey key) throws IOException{ if(key.isAcceptable()){ //客户端的连接请求事件 handlerAccept(key); }else if(key.isReadable()){ //处理客户端发送的数据 handelerRead(key); } } public void handlerAccept(SelectionKey key) throws IOException { ServerSocketChannel serverSocketChannel=(ServerSocketChannel) key.channel(); //建立与客户端连接的通道 SocketChannel channel=serverSocketChannel.accept(); channel.configureBlocking(false); //给selector 绑定客户端,并且监听客户端发送的请求。即对于服务端来说是可读取到客户端的数据 //请求 channel.register(this.selector,SelectionKey.OP_READ); System.out.println("New Client connected"); } public void handelerRead(SelectionKey key) throws IOException { SocketChannel channel=(SocketChannel)key.channel(); //缓冲区的大小以实际情况来调整 ByteBuffer byteBuffer= ByteBuffer.allocate(1024); //读取数据, -- 示例客户端最大一次性发送1024 int read=channel.read(byteBuffer); if(read>0){ String readMsg=new String(byteBuffer.array()); System.out.println("Read message:"+readMsg); //响应客户端 ByteBuffer outBuffer=ByteBuffer.wrap((readMsg+" is Ok").getBytes()); channel.write(outBuffer); }else{ System.out.println("client closed."); key.cancel(); } }}
操作系统IO Selector 模型类似