使用Java7的AIO实现非阻塞通信
来源:互联网 发布:fifo淘汰算法 编辑:程序博客网 时间:2024/06/02 00:18
为何要用AIO呢?效率更高。
AsynchronousServerSocketChannel用于服务器端,只要三步
1.调用open()静态方法创建AsynchronousServerSocketChannel。
2.调用AsynchronousServerSocketChannel的bind()方法让它在指定的IP地址,指定端口监听。
3.调用AsynchronousServerSocketChannel的accept()方法接受请求。
import java.net.*;import java.nio.*;import java.nio.channels.*;import java.util.concurrent.*;public class SimpleAIOServer{static final int PORT = 30000;public static void main(String[] args)throws Exception{try(// ①创建AsynchronousServerSocketChannel对象。AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open()){// ②指定在指定地址、端口监听。serverChannel.bind(new InetSocketAddress(PORT));while (true){// ③采用循环接受来自客户端的连接Future<AsynchronousSocketChannel> future= serverChannel.accept();// 获取连接完成后返回的AsynchronousSocketChannelAsynchronousSocketChannel socketChannel = future.get();// 执行输出。socketChannel.write(ByteBuffer.wrap("欢迎你来自AIO的世界!".getBytes("UTF-8"))).get();}}}}
AsynchronousSocketChannel用于客户端,它的用法分三步
1.调用open静态方法创建AsynchronousSocketChannel。
2.调用AsynchronousSocketChannel的connect()方法连接到指定的IP地址,指定端口的服务器
3.调用read() , write()方法。
SimpleAIOClient.java
import java.net.*;import java.nio.*;import java.nio.channels.*;import java.nio.charset.*;public class SimpleAIOClient{static final int PORT = 30000;public static void main(String[] args)throws Exception{// 用于读取数据的ByteBuffer。ByteBuffer buff = ByteBuffer.allocate(1024);Charset utf = Charset.forName("utf-8");try(// ①创建AsynchronousSocketChannel对象AsynchronousSocketChannel clientChannel = AsynchronousSocketChannel.open()){// ②连接远程服务器clientChannel.connect(new InetSocketAddress("127.0.0.1" , PORT)).get(); //④buff.clear();// ③从clientChannel中读取数据clientChannel.read(buff).get(); //⑤buff.flip();// 将buff中内容转换为字符串String content = utf.decode(buff).toString();System.out.println("服务器信息:" + content);}}}
再使用AIO开发聊天室
AIOServer.java
import java.net.*;import java.io.*;import java.util.*;import java.nio.*;import java.nio.channels.*;import java.nio.charset.*;import java.util.concurrent.*;public class AIOServer{static final int PORT = 30000;final static String UTF_8 = "utf-8";static List<AsynchronousSocketChannel> channelList= new ArrayList<>();public void startListen() throws InterruptedException,Exception {// 创建一个线程池ExecutorService executor = Executors.newFixedThreadPool(20);// 以指定线程池来创建一个AsynchronousChannelGroupAsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withThreadPool(executor);// 以指定线程池来创建一个AsynchronousServerSocketChannelAsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open(channelGroup)// 指定监听本机的PORT端口.bind(new InetSocketAddress(PORT));// 使用CompletionHandler接受来自客户端的连接请求serverChannel.accept(null, new AcceptHandler(serverChannel)); //①} public static void main(String[] args)throws Exception{AIOServer server = new AIOServer();server.startListen();}}// 实现自己的CompletionHandler类class AcceptHandler implementsCompletionHandler<AsynchronousSocketChannel, Object>{private AsynchronousServerSocketChannel serverChannel; public AcceptHandler(AsynchronousServerSocketChannel sc){this.serverChannel = sc;}// 定义一个ByteBuffer准备读取数据ByteBuffer buff = ByteBuffer.allocate(1024); // 当有客户端连接上的时候触发该方法,将客户端的AsynchronousSocketChannel传入,以便发送数据@Overridepublic void completed(final AsynchronousSocketChannel sc, Object attachment){// 记录新连接的进来的ChannelAIOServer.channelList.add(sc);// 准备接受客户端的下一次连接serverChannel.accept(null , this);sc.read(buff , null , new CompletionHandler<Integer,Object>() //② 读取客户端的数据,数据在buff里{@Overridepublic void completed(Integer result //这里表示当客户端AsynchronousSocketChannel完成一次IO,调用此方法, Object attachment){buff.flip();// 将buff中内容转换为字符串String content = StandardCharsets.UTF_8.decode(buff).toString();// 遍历每个Channel,将收到的信息写入各Channel中for(AsynchronousSocketChannel c : AIOServer.channelList){try{c.write(ByteBuffer.wrap(content.getBytes(AIOServer.UTF_8))).get();}catch (Exception ex){ex.printStackTrace();}}buff.clear();// 读取下一次数据sc.read(buff , null , this);}@Overridepublic void failed(Throwable ex, Object attachment){System.out.println("读取数据失败: " + ex);// 从该Channel读取数据失败,就将该Channel删除AIOServer.channelList.remove(sc);}});}@Overridepublic void failed(Throwable ex, Object attachment){System.out.println("连接失败: " + ex);}}AIOClient.java
import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.net.*;import java.nio.*;import java.nio.channels.*;import java.nio.charset.*;import java.util.concurrent.*;/** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */public class AIOClient{final static String UTF_8 = "utf-8";final static int PORT = 30000;// 与服务器端通信的异步ChannelAsynchronousSocketChannel clientChannel;JFrame mainWin = new JFrame("多人聊天");JTextArea jta = new JTextArea(16 , 48);JTextField jtf = new JTextField(40);JButton sendBn = new JButton("发送");public void init(){mainWin.setLayout(new BorderLayout());jta.setEditable(false);mainWin.add(new JScrollPane(jta), BorderLayout.CENTER);JPanel jp = new JPanel();jp.add(jtf);jp.add(sendBn);//发送消息的Action,Action是ActionListener的子接口Action sendAction = new AbstractAction(){public void actionPerformed(ActionEvent e){String content = jtf.getText();if (content.trim().length() > 0){try{// 将content内容写入Channel中clientChannel.write(ByteBuffer.wrap(content.trim().getBytes(UTF_8))).get(); //①}catch (Exception ex){ex.printStackTrace();}}// 清空输入框jtf.setText("");}};sendBn.addActionListener(sendAction);//将Ctrl+Enter键和"send"关联jtf.getInputMap().put(KeyStroke.getKeyStroke('\n', java.awt.event.InputEvent.CTRL_MASK) , "send");//将"send"和sendAction关联jtf.getActionMap().put("send", sendAction);mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);mainWin.add(jp , BorderLayout.SOUTH);mainWin.pack();mainWin.setVisible(true);}public void connect()throws Exception{// 定义一个ByteBuffer准备读取数据final ByteBuffer buff = ByteBuffer.allocate(1024);// 创建一个线程池ExecutorService executor = Executors.newFixedThreadPool(80);// 以指定线程池来创建一个AsynchronousChannelGroupAsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withThreadPool(executor);// 以channelGroup作为组管理器来创建AsynchronousSocketChannelclientChannel = AsynchronousSocketChannel.open(channelGroup);// 让AsynchronousSocketChannel连接到指定IP、指定端口clientChannel.connect(new InetSocketAddress("127.0.0.1", PORT)).get(); jta.append("---与服务器连接成功---\n");buff.clear();clientChannel.read(buff, null, new CompletionHandler<Integer,Object>() //②{@Overridepublic void completed(Integer result, Object attachment){buff.flip();// 将buff中内容转换为字符串String content = StandardCharsets.UTF_8.decode(buff).toString();// 显示从服务器端读取的数据jta.append("某人说:" + content + "\n");buff.clear();clientChannel.read(buff , null , this);}@Override public void failed(Throwable ex, Object attachment){System.out.println("读取数据失败: " + ex);}});}public static void main(String[] args) throws Exception{AIOClient client = new AIOClient();client.init();client.connect();}}
0 0
- 使用Java7的AIO实现非阻塞通信
- AIO实现非阻塞Socket通信
- 使用NIO实现非阻塞式的网络通信
- 使用NIO实现非阻塞Socket通信
- 使用NIO实现非阻塞Socket通信
- NIO实现TCP的非阻塞通信
- 使用非阻塞方式的Socket通信
- 使用非阻塞通信的简单聊天工具
- linux AIO libaio和epoll实现非阻塞模型
- java 同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO
- 同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO
- Thinking in Java--使用NIO实现非阻塞Socket通信
- 使用NIO实现非阻塞Socket通信原理
- MPI非阻塞通信使用、性能分析与实现原理
- 使用 JSSE 和 NIO 实现非阻塞通信的一种快速方法
- java中使用nio包实现非阻塞的UDP通信
- 另一种实现非阻塞网络通信的方法———使用libev
- Linux内核追踪[4.13] AIO的非阻塞优化
- 获取计算机的IP和MAC地址
- easyUI树
- 多个线程访问共享对象和数据的方式
- JavaScript 获取鼠标点击坐标五种方式及兼容性
- eclipse中怎么去掉Js/javsscript报错信息
- 使用Java7的AIO实现非阻塞通信
- java-学习路线
- 汉诺塔问题
- 彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
- JavaScript之完整版学习包含ES6
- 单例模式实例
- jQuery中.bind()和.live()的区别
- 关于CSS的定位问题
- [3]FPGA双端口RAM操作(乒乓操作)