Java nio 实现socket异步通信 (对Java nio 实习笔记五中内容做一纠正)
服务器端代码实现:
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.nio.charset.Charset; import java.util.Calendar; import java.util.Iterator; public class TestServer { public static void main(String[] args) { new Thread(new EchoServer(1982)).start(); } } class EchoServer implements Runnable { //要监听的端口号 private int port; //生成一个信号监视器 private Selector s; //读缓冲区 private ByteBuffer r_bBuf = ByteBuffer.allocate(1024); private ByteBuffer w_bBuf; public EchoServer(int port) { this.port = port; try { s = Selector.open(); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { //生成一个ServerScoket通道的实例对象,用于侦听可能发生的IO事件 ServerSocketChannel ssc = ServerSocketChannel.open(); //将该通道设置为异步方式 ssc.configureBlocking(false); //绑定到一个指定的端口 ssc.socket().bind(new InetSocketAddress(port)); //注册特定类型的事件到信号监视器上 ssc.register(s, SelectionKey.OP_ACCEPT); System.out.println("The server has been launched..."); while(true) { //将会阻塞执行,直到有事件发生 s.select(); Iterator<SelectionKey> it = s.selectedKeys().iterator(); while(it.hasNext()) { SelectionKey key = it.next(); //key定义了四种不同形式的操作 switch(key.readyOps()) { case SelectionKey.OP_ACCEPT : dealwithAccept(key); break; case SelectionKey.OP_CONNECT : break; case SelectionKey.OP_READ : dealwithRead(key); break; case SelectionKey.OP_WRITE : break; } //处理结束后移除当前事件,以免重复处理 it.remove(); } } } catch (IOException e) { e.printStackTrace(); } } //处理接收连接的事件 private void dealwithAccept(SelectionKey key) { try { System.out.println("新的客户端请求连接..."); ServerSocketChannel server = (ServerSocketChannel)key.channel(); SocketChannel sc = server.accept(); sc.configureBlocking(false); //注册读事件 sc.register(s, SelectionKey.OP_READ); System.out.println("客户端连接成功..."); } catch (IOException e) { e.printStackTrace(); } } //处理客户端发来的消息,处理读事件 private void dealwithRead(SelectionKey key) { try { SocketChannel sc = (SocketChannel)key.channel(); System.out.println("读入数据"); r_bBuf.clear(); //将字节序列从此通道中读入给定的缓冲区r_bBuf sc.read(r_bBuf); r_bBuf.flip(); String msg = Charset.forName("UTF-8").decode(r_bBuf).toString(); if(msg.equalsIgnoreCase("time")) { w_bBuf = ByteBuffer.wrap(getCurrentTime().getBytes("UTF-8")); sc.write(w_bBuf); w_bBuf.clear(); } else if(msg.equalsIgnoreCase("bye")) { sc.write(ByteBuffer.wrap("已经与服务器断开连接".getBytes("UTF-8"))); sc.socket().close(); } else { sc.write(ByteBuffer.wrap(msg.getBytes("UTF-8"))); } System.out.println(msg); System.out.println("处理完毕..."); r_bBuf.clear(); try { Thread.currentThread(); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } private String getCurrentTime() { Calendar date = Calendar.getInstance(); String time = "服务器当前时间:" + date.get(Calendar.YEAR) + "-" + date.get(Calendar.MONTH)+1 + "-" + date.get(Calendar.DATE) + " " + date.get(Calendar.HOUR) + ":" + date.get(Calendar.MINUTE) + ":" + date.get(Calendar.SECOND); return time; } }
客户端代码实现:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class TestClient { public static void main(String[] args) { new MiniClient("localhost", 1982); } } class MiniClient { private SocketChannel sc; private ByteBuffer w_bBuf; private ByteBuffer r_bBuf = ByteBuffer.allocate(1024); public MiniClient(String host, int port) { try { InetSocketAddress remote = new InetSocketAddress(host, port); sc = SocketChannel.open(); sc.connect(remote); if(sc.finishConnect()) { System.out.println("已经与服务器成功建立连接..."); } while(true) { if(!sc.socket().isConnected()) { System.out.println("已经与服务器失去了连接..."); return ; } BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); System.out.println("读入一行数据,开始发送..."); w_bBuf = ByteBuffer.wrap(str.getBytes("UTF-8")); //将缓冲区中数据写入通道 sc.write(w_bBuf); System.out.println("数据发送成功..."); w_bBuf.clear(); System.out.println("接收服务器端响应消息..."); try { Thread.currentThread(); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } r_bBuf.clear(); //将字节序列从此通道中读入给定的缓冲区r_bBuf sc.read(r_bBuf); r_bBuf.flip(); String msg = Charset.forName("UTF-8").decode(r_bBuf).toString(); System.out.println(msg); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
转载自:http://blog.csdn.net/tsyj810883979/article/details/6882977