为什么80%的码农都做不了架构师?>>>
1.BIO的例子。
/** * @author lilinshen * @title bio (Blocking io) 同步阻塞io * @description jdk1.4 io 都是bio * @date 2018/8/21 15:02 */ public class BIOServer { public static void main(String[] args) { server1(); } /** * 传统,只能是1对1 */ public static void server1() { ServerSocket server = null; Socket socket = null; InputStream in = null; OutputStream out = null; try { server = new ServerSocket(8000); System.out.println("服务端启动成功,监听端口为8000,等待客户端连接..."); socket = server.accept(); //阻塞 客户端 in = socket.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; //读取客户端的数据 while ((len = in.read(buffer)) > 0) { System.out.println(new String(buffer, 0, len)); } //向客户端写数据 out = socket.getOutputStream(); out.write("hello everybody!".getBytes()); } catch (IOException e) { e.printStackTrace(); } } /** * 多线程 */ public static void server2() { ServerSocket server = null; try { server = new ServerSocket(8000); System.out.println("服务端启动成功,监听端口为8000,等待客户端连接..."); while (true) { Socket socket = new Socket(); //针对每个连接创建一个线程,去处理io操作 //socket来了之后就创建线程 不合理 new Thread(new BIOServerHandler(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } } /** * 线程池 */ public static void server3() { ServerSocket server = null; ExecutorService executorService = Executors.newFixedThreadPool(60); try { server = new ServerSocket(8000); System.out.println("服务端启动成功,监听端口为8000,等待客户端连接..."); while (true) { Socket socket = new Socket(); //使用线程池中的线程去执行每个对应的任务 executorService.execute(new BIOServerHandler(socket)); } } catch (IOException e) { e.printStackTrace(); } } }
/** * @author lilinshen * @title bio serverhandler * @description 请填写相关描述 * @date 2018/8/21 15:20 */ public class BIOServerHandler implements Runnable { private Socket socket; public BIOServerHandler(Socket socket) { this.socket = socket; } /** * 当前线程要执行的任务 */ @Override public void run() { InputStream in = null; try { in = socket.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; //读取客户端的数据 while ((len = in.read(buffer)) > 0) { System.out.println(new String(buffer, 0, len)); } //向客户端写数据 OutputStream out = socket.getOutputStream(); out.write("hello everybody!".getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
2.nio例子
/** * @author lilinshen * @title nio 同步非阻塞 * @description 是对bio的改进,但是api比较复杂。 * @date 2018/8/21 15:53 */ public class NIOServer { private int port; private InetSocketAddress address = null; private Selector selector; public NIOServer(int port) { try { this.port = port; address = new InetSocketAddress(this.port); ServerSocketChannel server = ServerSocketChannel.open(); //服务器通道设置成非阻塞的模式 //server.configureBlocking(false); server.socket().bind(address); selector = Selector.open(); //每当有客户端连接上来的时候,默认它已经连接上来了 //而这个连接我需要记录一个它的状态 connected server.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服务器启动成功:" + this.port); } catch (IOException e) { e.printStackTrace(); } } //Selector开始轮询 public void listen() { try { while (true) { //accept()阻塞的,select()也是阻塞的 int wait = this.selector.select(); if (wait == 0) { continue; } //SelectionKey代表的是客户端和服务端连接的一个关键 Setkeys = this.selector.selectedKeys(); Iterator i = keys.iterator(); while (i.hasNext()) { SelectionKey key = i.next(); //针对每一个客户端进行相应的操作 process(key); i.remove(); } } } catch (IOException e) { e.printStackTrace(); } } //处理每一个客户端 key private void process(SelectionKey key) throws IOException { ByteBuffer buffer = ByteBuffer.allocate(1024); if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); //客户端一旦连接上来 读写 //往这个selector上注册key read 接下来可以读 client.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel client = (SocketChannel) key.channel(); int len = client.read(buffer); //读取完成了 if (len > 0) { buffer.flip(); //固定 String content = new String(buffer.array(), 0, len); client.register(selector, SelectionKey.OP_WRITE); System.out.println(content); } buffer.clear(); } else if (key.isWritable()) { SocketChannel client = (SocketChannel) key.channel(); client.write(buffer.wrap("hello world".getBytes())); client.close(); } } public static void main(String[] args) { new NIOServer(8000).listen(); } }
3.netty例子
/** * @author lilinshen * @title netty 异步非阻塞 * @description 是对nio的封装,新增了异步。 * @date 2018/8/21 16:44 */ public class NettyServer { /** * netty 异步非阻塞 * 在nio中的selector.select() 使用了多线程。 */ public static void server() { //Boss线程 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new HttpRequestEncoder()); ch.pipeline().addLast(new HttpRequestDecoder()); //添加自己的handler //... } }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true); //绑定服务端口 阻塞的过程 System.out.println("服务端开启等待客户端连接..."); ChannelFuture f = b.bind(8000).sync(); //开始接收客户端 f.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { // 优雅的推出程序 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) { server(); } }