java NIO实现

NIO工作流程如图
在这里插入图片描述

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.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Service {

private static Charset charset=Charset.forName("UTF-8");

private static CharsetDecoder decoder=charset.newDecoder();

public static void main(String[] args) throws IOException {
	//1:创建一个注册中心
	Selector selector=Selector.open();
	//2创建通道
	ServerSocketChannel channel=ServerSocketChannel.open();
	int port=9200;
	//3把通道绑定到服务端口
	channel.bind(new InetSocketAddress(port));
	//4:把通道注册到selector 非阻塞
	channel.configureBlocking(false);
	channel.register(selector, SelectionKey.OP_ACCEPT);
	 int connectionCount=0;
	 ExecutorService executorService=Executors.newFixedThreadPool(3);
	 while(true){
		 //得到就绪的channel的数量
		int readChannelCount=selector.select(); 
		if(readChannelCount==0){
			continue;	
		}
		//得到就绪的channel的key
		Set<SelectionKey> selectedKeys=selector.selectedKeys();
		Iterator<SelectionKey> keyIterator=selectedKeys.iterator();
		while(keyIterator.hasNext()){
			SelectionKey key=keyIterator.next();
			//可接收的通道
			if(key.isAcceptable()){
				ServerSocketChannel channel2=(ServerSocketChannel) key.channel();
				SocketChannel socketChannel=channel2.accept();
				socketChannel.configureBlocking(false);
				socketChannel.register(selector, SelectionKey.OP_READ, ++connectionCount);
			}else if(key.isReadable()){
				//交给线程处理读取数据
				executorService.execute(new SocketProcess(key));
				key.cancel();
			}
			keyIterator.remove();
		}
	 }
	
}

static class SocketProcess implements Runnable{
	SelectionKey key;
	private SocketProcess(SelectionKey key){
		super();
		this.key=key;
	}
	
	@Override
	public void run() {
		try{
			System.out.println("连接:"+key.attachment()+"发来了:"+readFormChannel());
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private String readFormChannel() throws IOException{
		SocketChannel channel=(SocketChannel) key.channel();
		int size=1024;
		ByteBuffer buffer=ByteBuffer.allocateDirect(size);
		//定义一个更大的buffer
		ByteBuffer bigBuffer=null;
		int count=0;
		while((channel.read(buffer))!=-1){
			count++;
			ByteBuffer temp=ByteBuffer.allocateDirect(size*(count+1));
			if(bigBuffer!=null){
				bigBuffer.flip();
				temp.put(bigBuffer);
			}
			bigBuffer=temp;
			buffer.flip();
			bigBuffer.put(buffer);
			buffer.clear();
			if(bigBuffer!=null){
				bigBuffer.flip();
				try{
					return decoder.decode(bigBuffer).toString();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
		return null;
	}
}

}

package nio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Scanner;

public class Client {

private static Charset charset=Charset.forName("UTF-8");

public static void main(String[] args) {
	
	try{
		SocketChannel channel=SocketChannel.open();
		boolean connection=channel.connect(new InetSocketAddress("localhost", 9200));
		System.out.println(connection);
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入:");
		String message=scanner.nextLine();
		ByteBuffer buffer=ByteBuffer.wrap(message.getBytes(charset));
		while(buffer.hasRemaining()){
			int writedCount=channel.write(buffer);
		}
	}catch(Exception e){
		e.printStackTrace();
	}
	
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值