网络编程复习(三):NIO模式
发布日期:2021-11-13 10:21:49 浏览次数:13 分类:技术文章

本文共 4165 字,大约阅读时间需要 13 分钟。

关于NIO,就是同步非阻塞,虽然效率会提高,但实现起来的有点麻烦,所以实际开发中用的很少,更多的是用Netty框架使用网络Socket,Netty其实是对JDK的nio的一个优化封装,实现起来更加方便,后续也将会介绍,下面看看流程图解:

client端:

package 网络编程_NIO;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;public class Client {	public static void main(String[] args) {		//定义socket连接的地址与端口		InetSocketAddress address = new InetSocketAddress("127.0.0.1",8888);		//通道		SocketChannel channel = null;		//缓冲区		ByteBuffer buffer = ByteBuffer.allocate(1024);		try {			//打开通道			channel = SocketChannel.open();			//连接地址			channel.connect(address);			while(true){				byte[] bys = new byte[1024];				//控制台读取数据1024字节				System.in.read(bys);				//数据放入缓冲区				buffer.put(bys);				//复位				buffer.flip();				//通道将缓冲区数据写给服务端				channel.write(buffer);				//清空缓冲区				buffer.clear();							}		} catch (Exception e) {			e.printStackTrace();		}finally {			if(channel!=null){				try {					channel.close();				} catch (IOException e) {					// TODO Auto-generated catch block					e.printStackTrace();				}			}		}	}}
server端:

package 网络编程_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.util.Iterator;public class Server implements Runnable{	private Selector selector;	private ByteBuffer readerBuffer = ByteBuffer.allocate(1024);	//private ByteBuffer writerBuffer = ByteBuffer.allocate(1024);	public  Server(int port) {		try {			//打开多路复用器			this.selector = Selector.open();			//打开连接通道			ServerSocketChannel socketChannel = ServerSocketChannel.open();			//设置为非阻塞模式			socketChannel.configureBlocking(false);			//通道绑定端口监听			socketChannel.bind(new InetSocketAddress(port));			//通道注册到多路复用器上			socketChannel.register(this.selector, SelectionKey.OP_ACCEPT);			System.out.println("Server started..."+port);		} catch (Exception e) {			// TODO: handle exception		}	}	@Override	public void run() {		while(true){			try {				//多路复用器开始监听				this.selector.select();				//返回多路复用器选择的结果集				Iterator
keys = this.selector.selectedKeys().iterator(); //开始遍历 while(keys.hasNext()){ //获得选择的第一个元素 SelectionKey key = keys.next(); //将选择的元素从容器中移除 keys.remove(); //如果元素可用 if(key.isValid()){ //如果为阻塞状态 if(key.isAcceptable()){ this.accept(key); } //可读 if(key.isReadable()){ this.read(key); } //可写 if(key.isWritable()){ this.writer(key); } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void writer(SelectionKey key) { /*this.writerBuffer.clear(); SocketChannel channel = (SocketChannel) key.channel(); byte[] bys = new String("服务端已经接受到你的数据").getBytes(); writerBuffer.put(bys); writerBuffer.flip(); try { channel.write(writerBuffer); writerBuffer.clear(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ } private void read(SelectionKey key) { try { this.readerBuffer.clear(); SocketChannel channel = (SocketChannel) key.channel(); int count = channel.read(readerBuffer); if(count == -1){ key.channel().close(); key.cancel(); return; } this.readerBuffer.flip(); byte[] bys = new byte[this.readerBuffer.remaining()]; this.readerBuffer.get(bys); String body = new String(bys).trim(); System.out.println("Server"+body); //channel.register(this.selector, SelectionKey.OP_WRITE); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void accept(SelectionKey key) { try { ServerSocketChannel socketChannel = (ServerSocketChannel) key.channel(); SocketChannel channel = socketChannel.accept(); channel.configureBlocking(false); //阻塞状态变为可读状态 channel.register(this.selector, SelectionKey.OP_READ); } catch (Exception e) { // TODO: handle exception } } public static void main(String[] args) { new Thread(new Server(8888)).start(); }}
这里我并没有实现服务端向客户端写数据,因为这种情况客户端也像一个服务端了,实现起来和server端代码很相似,加一个Selector就行了,这里感觉很麻烦,所以没有实现,有兴趣的朋友可以试下。

转载地址:https://blog.csdn.net/Lee_Ho_/article/details/78122588 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:网络编程复习(四):AIO
下一篇:网络编程复习(二):JDK1.5之前的伪异步BIO编程

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月08日 14时50分53秒