Simple AIO communication mode

Compared to BIO (blocked IO, B means Blocking), the performance of NIO (synchronous non-blocking IO) and AIO (asynchronous non-blocking IO) is much higher. Asynchronous communication does not use repeated polling, and the main program will not be blocked in an infinite loop, but will continue to execute. If a message is received, the callback function will be called automatically to complete the specified operation. The complexity of NIO and AIO is obviously greater than that of BIO

The author wrote a NIO communication window a few days ago, this time I wrote an AIO window. Mainly use
AsynchronousServerSocketChannel, AsynchronousSocketChannel. Pass a CompletionHandler to the server.accept method, and implement the completed and failed methods. The complete method is a callback function, this method will be called when accept is successfully executed. And the package word will also be passed to ComletionHandler.

This is the effect when it runs: the
Enter the interface
chat window
code is as follows:

package Message2;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/*
 * @version:2.0
 * @author:阿基
 * @time:2020/8/22
 */
public class Message2 
{
    
    
	public static void main(String[] args)
	{
    
    
		EventQueue.invokeLater(()->{
    
    
			MessageFrame frame=new MessageFrame("Message 2.0");
			frame.setVisible(true);
		});
	}
}

class MessageFrame extends JFrame
{
    
    
	private JButton connectButton;
	private JButton sendButton;
	private JButton cancelButton;
	private JButton acceptButton;
	private JTextArea messages;
    String name;
	private JLabel hostLabel;
	private JLabel portLabel;
	private JTextField hostField;
	private JTextField portField;
	private JTextField messageField;
	private Server server;
	private SocketChannel socketChannel=null;
	public MessageFrame(String title)
	{
    
    
		super(title);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new BorderLayout());
		hostLabel=new JLabel("客户机IP地址:");
		hostField=new JTextField(10);
		portLabel=new JLabel("客户机端口");
		portField=new JTextField(5);
		JPanel northPanel=new JPanel();
		connectButton=new JButton("连接");
		WindowListener listener=new MyWindowHandler();
		addWindowListener(listener);
		connectButton.addActionListener(event->{
    
    
			String ip=hostField.getText().trim();
			int port =Integer.parseInt(portField.getText().trim());
			if(connect(ip,port))
				messages.append("连接成功\n");
		});
		northPanel.add(hostLabel,BorderLayout.NORTH);
		northPanel.add(hostField,BorderLayout.NORTH);
		northPanel.add(portLabel,BorderLayout.NORTH);
		northPanel.add(portField,BorderLayout.NORTH);
		northPanel.add(connectButton,BorderLayout.NORTH);
		add(northPanel,BorderLayout.NORTH);
		
		messages=new JTextArea("本机的IP地址查询DOS命令:ipconfig\n",20,60);
		add(new JScrollPane(messages),BorderLayout.CENTER);
		
		acceptButton=new JButton("开启服务器");
		sendButton=new JButton("发送信息");
		cancelButton=new JButton("退出");
		messageField=new JTextField(20);
			
		sendButton.addActionListener(event->{
    
    
		sendMessage();
		});
		
		acceptButton.addActionListener(event->{
    
    
			server=new Server();
			server.start();
		});
		
		cancelButton.addActionListener(event->
		{
    
    
			System.exit(1);
			
		});
		JPanel southPanel=new JPanel();
		southPanel.add(messageField,BorderLayout.CENTER);
		southPanel.add(acceptButton,BorderLayout.SOUTH);
		southPanel.add(sendButton,BorderLayout.SOUTH);
		southPanel.add(cancelButton,BorderLayout.SOUTH);
		
		add(southPanel,BorderLayout.SOUTH);
		pack();
		
	}
	//判断是否可以连接成功
	private boolean connect(String ip, int port) 
	{
    
    
		try {
    
    
			socketChannel=SocketChannel.open();
			return socketChannel.connect(new InetSocketAddress(ip,port));
		}catch(IOException e)
		{
    
    
			messages.append("连接失败:"+e);
			return false;
		}
	}

		
		public void sendMessage()
		{
    
    
			//输入IP和端口
			String ip=hostField.getText().trim();
			int port =Integer.parseInt(portField.getText().trim());
	       
			try {
    
    
				//创建通道,并建立连接
			socketChannel=SocketChannel.open();
			socketChannel.connect(new InetSocketAddress(ip,port));
			//设置为非阻塞模式
			socketChannel.configureBlocking(false);
			String word=messageField.getText();
			word=name+":"+word;
			if(word!=""|word!=null) {
    
    
				//建立缓存区
			ByteBuffer writeBuffer=ByteBuffer.allocate(1024*10);
			//将输入的字符串以“UTF-”转换为数组
			byte[] bytes=word.getBytes("UTF-8");
			//将数组写入缓存区
			writeBuffer.put(bytes);
			//翻转缓存区, The limit is set to 
			//the current position and then
			//the position is set to zero. If the mark is defined then it is discarded. 
			writeBuffer.flip();
			socketChannel.write(writeBuffer);
			messages.append(word+"\n");
			messageField.setText("");
			}
			}catch(IOException e)
			{
    
    
				messages.append("发送消息时出错:"+e);
			}
		}
		
	//创建服务器
	class Server extends Thread
	{
    
    
	
		@Override
		public void run()
		{
    
    
			try
			{
    
    
			AsynchronousServerSocketChannel server=AsynchronousServerSocketChannel.open();
			int port=Integer.parseInt(messageField.getText());
			server.bind(new InetSocketAddress(port));
			messages.append("服务器已开启,端口为"+port+"\n");
			messageField.setText("");
			server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
    
    
				

				@Override
				public void completed(AsynchronousSocketChannel channel, Void attachment)
				{
    
    
					server.accept(null,this);
					
					ByteBuffer  readBuffer=ByteBuffer.allocate(1024*10);
					channel.read(readBuffer, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {
    
    

						@Override
						public void completed(Integer result, ByteBuffer attachment) 
						{
    
    
							attachment.flip();	
							String word = null;
							try {
    
    
								word = new String(attachment.array(),"UTF-8");
							} catch (UnsupportedEncodingException e) {
    
    
								e.printStackTrace();
							}
							messages.append(word+"\n");
						}

						@Override
						public void failed(Throwable exc, ByteBuffer attachment) {
    
    
							messages.append("写入过程出现错误:"+exc+"\n");
							
						}
					});
				}

				@Override
				public void failed(Throwable exc, Void attachment) {
    
    
					// TODO Auto-generated method stub
					
				}
				
			});
			}catch(IOException e)
			{
    
    
				messages.append("服务器已经创建:"+e+"\n");
			}
		}
	}
	class MyWindowHandler extends WindowAdapter
	{
    
    
		public void  windowOpened(WindowEvent e)
		{
    
    
			name=JOptionPane.showInputDialog(null, "请输入昵称", "欢迎", JOptionPane.INFORMATION_MESSAGE);
			messages.append("你的昵称是:"+name+"\n");
		}
	}
}

Guess you like

Origin blog.csdn.net/m0_47202518/article/details/108262037