OIO和NIO

1.先谈OIO
传统的socket的方式。在server.acept()和is.read()处会发生阻塞,在单线程情况下,只能有一个客户端对应服务端访问。

代码实现:
1.创建服务端服务
2.服务运行,在指定接口监听
3.当有请求达到时,接收客户端请求
4.处理请求

package IO;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class OIO {

	public static void main(String[] args) {

		ExecutorService executorService = Executors.newCachedThreadPool();

		try {
//			ServerSocket在10101端口监听
			ServerSocket server = new ServerSocket(10101);
			System.out.println("连接到服务器");

			while (true) {
				// 从端口监听到socket并获取到socket对象
				Socket accept = server.accept();
				// 处理socket消息
				executorService.execute(new Runnable() {

					@Override
					public void run() {
						// 多线程情况下监听
						// TODO Auto-generated method stub
						try {
							handler(accept);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});

			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private static void handler(Socket accept) throws IOException {
		// TODO Auto-generated method stub
		// 读socket里封装的字节流信息
		InputStream is = accept.getInputStream();
		// 创建字节数组
		byte[] by = new byte[1024];
		//
		while (true) {
			//
			int len = is.read(by);
			// 如果不是最后一个字节
			if (len != -1) {
				System.out.println(new String(by, 0, len));
			}

		}

	}
}

采用多线程可实现多个服务端访问,但是耗费资源。

NIO.非阻塞式IO
代码实现思路
1.初始化服务 服务对应有端口
1.1创建一个socketServer通道,并初始化通道(设置非阻塞,通道绑定端口)
1.2创建一个通道管理者。绑定到对应的通道。并设置SelectionKey.OP_ACCEPT事件(这个事件设置完成后,管理者会返回)
initServer(int port)

2.服务监听。
3.请求处理
3.1:处理连接请求。
3.2:处理读的请求。

package NIO;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
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 NIOServer {
	private Selector selector;
	
	//1.初始化服务
	public void initServer(int port) throws IOException
	{
		
		//1.先获得一个通道
		ServerSocketChannel socketChannel = ServerSocketChannel.open();
//		设置非阻塞
		socketChannel.configureBlocking(false);
		//将通道绑定到对应端口
		socketChannel.socket().bind(new InetSocketAddress(port));
		//2.获得一个通道管理器
		selector = Selector.open();
		//3.注册绑定通道和通道管理器
//		SelectionKey.OP_ACCEPT  当事件到达时,通道管理器会返回,否则一直阻塞
		socketChannel.register(selector, SelectionKey.OP_ACCEPT);
	}

	//2.请求监听
	public void serverlisten() throws IOException{
		//无限循环监听
		 while(true)
		 {//监听到事件到达,返回
		  selector.select();
		  //使用迭代器轮询监听
		  Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
		  while(iterator.hasNext())
		  {
			 //先获取selectionKey
			  SelectionKey selectionKey = iterator.next();
//			  再移除已经访问的
			  iterator.remove();
			  //根据selectionKey来处理请求
			  handler(selectionKey);
		  }
		 }
	}
	
	3.处理请求
	public void handler(SelectionKey key) throws IOException {
//		 3.1:处理接受请求
		if(key.isAcceptable())
		{//允许接受的则先处理接收请求
			//提取通道信息
			ServerSocketChannel server = (ServerSocketChannel) key.channel();
			//获取客户端连接通道
			SocketChannel channel = server.accept();
			channel.configureBlocking(false);//设置非阻塞
			//设置读权限
			channel.register(selector, SelectionKey.OP_READ);	
		}
		if(key.isReadable()) {
//			3.2:处理读请求
			//
			SocketChannel channel = (SocketChannel) key.channel();
			//创建缓冲区
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			int read = channel.read(buffer);
			//if
			if(read>0)
			{
				//
				byte[] bs = buffer.array();
				String msg=new String(bs);
				System.out.println("收到消息:"+msg);
				
				ByteBuffer src=ByteBuffer.wrap(bs);
				channel.write(src);
			}
			else {
				System.out.println("没有服务,已关闭");
				key.cancel();
			}
		}
	}
	

//  
	public static void main(String[] args) throws IOException {
		NIOServer nIOServer=new NIOServer();
		nIOServer.initServer(10101);
		nIOServer.serverlisten();
	
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值