版权声明:如果喜欢的话,可以撩我哟,此处没有联系方式,想要就自己找哈。 https://blog.csdn.net/qq_39384184/article/details/84792626
AIO 编程为每个请求新建一个线程。
- AioServer:
import java.io.IOException; import java.net.InetSocketAddress; import java.net.StandardSocketOptions; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; public class AioServer { public static int PORT = 8200; public static int BUFFER_SIZE = 1024; public static String CHARSET = "utf-8"; // 默认编码 public static CharsetDecoder decoder = Charset.forName(CHARSET).newDecoder(); // 解码 private int port; private AsynchronousServerSocketChannel serverChannel; public AioServer(int port) throws IOException { this.port = port; } private void listen() throws Exception { // 打开一个服务通道, 绑定服务端口 this.serverChannel = AsynchronousServerSocketChannel.open().bind( new InetSocketAddress(port), 100); this.serverChannel.accept(this, new AcceptHandler()); Thread t = new Thread(() -> { while (true) { System.out.println("运行中..."); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); } /** * accept到一个请求时的回调 */ private class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, AioServer> { @Override public void completed(final AsynchronousSocketChannel client, AioServer attachment) { try { System.out.println("客户端地址:" + client.getRemoteAddress()); // tcp各项参数 client.setOption(StandardSocketOptions.TCP_NODELAY, true); client.setOption(StandardSocketOptions.SO_SNDBUF, 1024); client.setOption(StandardSocketOptions.SO_RCVBUF, 1024); if (client.isOpen()) { System.out.println("客户端已打开:" + client.getRemoteAddress()); final ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); buffer.clear(); client.read(buffer, client, new ReadHandler(buffer)); } } catch (Exception e) { e.printStackTrace(); } finally { attachment.serverChannel.accept(attachment, this);// 监听新的请求,递归调用。 } } @Override public void failed(Throwable exc, AioServer attachment) { try { exc.printStackTrace(); } finally { attachment.serverChannel.accept(attachment, this);// 监听新的请求,递归调用。 } } } /** * Read到请求数据的回调 */ private class ReadHandler implements CompletionHandler<Integer, AsynchronousSocketChannel> { private ByteBuffer buffer; public ReadHandler(ByteBuffer buffer) { this.buffer = buffer; } @Override public void completed(Integer result, AsynchronousSocketChannel attachment) { try { if (result < 0) {// 客户端关闭了连接 AioServer.close(attachment); } else if (result == 0) { System.out.println("空数据"); // 处理空数据 } else { // 读取请求,处理客户端发送的数据 buffer.flip(); CharBuffer charBuffer = AioServer.decoder.decode(buffer); System.out.println(charBuffer.toString()); // 接收请求 // 响应操作,服务器响应结果 buffer.clear(); String res = "服务端返回的消息"; buffer = ByteBuffer.wrap(res.getBytes()); attachment.write(buffer, attachment, new WriteHandler( buffer));// Response:响应。 } } catch (Exception e) { e.printStackTrace(); } } @Override public void failed(Throwable exc, AsynchronousSocketChannel attachment) { exc.printStackTrace(); AioServer.close(attachment); } } /** * Write响应完请求的回调 */ private class WriteHandler implements CompletionHandler<Integer, AsynchronousSocketChannel> { private ByteBuffer buffer; public WriteHandler(ByteBuffer buffer) { this.buffer = buffer; } @Override public void completed(Integer result, AsynchronousSocketChannel attachment) { buffer.clear(); AioServer.close(attachment); } @Override public void failed(Throwable exc, AsynchronousSocketChannel attachment) { exc.printStackTrace(); AioServer.close(attachment); } } public static void main(String[] args) { try { System.out.println("正在启动服务..."); AioServer server = new AioServer(PORT); server.listen(); } catch (Exception e) { e.printStackTrace(); } } private static void close(AsynchronousSocketChannel client) { try { client.close(); } catch (Exception e) { e.printStackTrace(); } } }
- AioClient:
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; public class AioClient { public static void main(String[] args) { String host = "localhost"; int port = 8200; String sendMsg = "send data from client ad"; connect(host, port, sendMsg.getBytes()); } public static void connect(String server, int servPort, byte[] data) { // 创建socket对象用于连接服务端socket Socket socket = null; try { socket = new Socket(server, servPort); System.out.println("连接服务器并发送数据..."); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); out.write(data); // 接收数据 // 目前收到的总字节长度 int totalBytesRcvd = 0; // 最后一次读取的字节长度 int bytesRcvd; // 将服务器返回消息读到data字节数组中 while (totalBytesRcvd < data.length) { bytesRcvd = in.read(data, totalBytesRcvd, data.length - totalBytesRcvd); if (bytesRcvd == -1) { throw new SocketException("连接中断..."); } totalBytesRcvd += bytesRcvd; } System.out.println("接收的数据:" + new String(data)); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally {// 关闭socket资源 try { if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
文章来源: AIO 编程