# NIO 实例demo-Client

xiaoxiao2021-02-28  123

NIO 实例demo-Client

Client部分包括Client和ClientHandle两部分其中Client的时序通信图如下

Client.java

Client端启动主函数如下

package MyTestNetty.Server; /** * Created by User on 2017/8/4. */ public class Client { public static void main(String[] args) { int port = 8080;//指定端口号 new Thread(new TimeClientHandle1("127.0.0.1",port),"myclient").start();//启动监听线程 } }

TimeClientHandle1.java

第二部分是ClientHandler部分代码如下:

package MyTestNetty.Server; 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; /** * Created by User on 2017/8/4. */ public class TimeClientHandle1 implements Runnable { private String host; private int port; private Selector selector; private SocketChannel socketChannel; private volatile boolean stop; public TimeClientHandle1(String host, int port) { this.host = host == null ? "127.0.0.1" : host; this.port = port; try { selector = Selector.open();//创建selector实例 socketChannel = SocketChannel.open();//创建socketChannel实例 socketChannel.configureBlocking(false);//设置为异步 } catch (IOException e) { e.printStackTrace(); System.exit(1); } } @Override public void run() { try{ doConnect(); }catch (IOException e){ e.printStackTrace(); System.exit(1); } while (!stop){//轮询查询可用的key try{ selector.select(1000); Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectionKeys.iterator(); SelectionKey key = null; while (it.hasNext()){ key = it.next(); it.remove(); try { hadleInput(key); } catch (Exception e){ if(key!=null){ key.cancel(); if(key.channel()!=null) key.channel().close(); } } } }catch (Exception e){ e.printStackTrace(); System.exit(1); } } // 多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动注册并关闭,所以不需要重新释放资源 if(selector!=null){ try { selector.close(); }catch (IOException e){ e.printStackTrace(); } } } private void hadleInput(SelectionKey key) throws IOException { if(key.isValid()){ SocketChannel sc = (SocketChannel)key.channel(); if(key.isConnectable()){ if(sc.finishConnect()){ sc.register(selector,SelectionKey.OP_READ); doWrite(sc);//向服务启发送请求(先写缓冲) }else{ System.exit(1); } } if(key.isReadable()){//读取服务端返回的数据,从还缓冲中读数据 // read data ByteBuffer readBuffer = ByteBuffer.allocate(1024); int readBytes = sc.read(readBuffer); if(readBytes>0){ readBuffer.flip(); byte[] bytes=new byte[readBuffer.remaining()]; readBuffer.get(bytes); String body = new String(bytes,"UTF-8"); System.out.println("Hello glad to see you : " + body); this.stop=true; } else if(readBytes<0){ // 对端链路关闭 key.cancel(); sc.close(); } else ; // 读到0字节,忽略 } } } private void doConnect() throws IOException { if(socketChannel.connect(new InetSocketAddress(host,port))){ socketChannel.register(selector,SelectionKey.OP_READ); doWrite(socketChannel); }else{ socketChannel.register(selector,SelectionKey.OP_CONNECT); } } private void doWrite(SocketChannel sc) throws IOException { byte[] req = "Clients ".getBytes(); ByteBuffer writeBuffer = ByteBuffer.allocate(req.length); writeBuffer.put(req); writeBuffer.flip(); sc.write(writeBuffer); if(!writeBuffer.hasRemaining()){ System.out.println("send order to server succeed!"); } } }

这一部分主要是包括向服务器发送请求,以及接受来自server的信息,启动运行后可输出一下结果表示服务端启动成功(本例中我们向服务器发送的是Clients 字符串)服务器给我们反馈的是Server)

并且在服务端的控制台输出如下:

这个简单的服务器客户端NIO通信的简单demo

转载请注明原文地址: https://www.6miu.com/read-36319.html

最新回复(0)