Java review--NIO实例:实现服务端和客户端的简单通信


客户端代码:

package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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;
import java.util.Set;

public class NIOServer {
	
	private int flag =1;
	private int blockSize=4096;
	private ByteBuffer sendbuffer =ByteBuffer.allocate(blockSize);//发送数据缓冲区
	private ByteBuffer receivebuffer =ByteBuffer.allocate(blockSize);//接收数据缓冲区
	private Selector selector;//选择器
	
	
	public NIOServer(int port) throws IOException{
		ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
		//设置是否组阻塞
		serverSocketChannel.configureBlocking(false);
		//创建客户端和服务端的socket.socket网络套接字,用来向网络发送请求,或者应答请求。
		ServerSocket serverSocket=serverSocketChannel.socket();
		//绑定socket地址,IP端口
		serverSocket.bind(new InetSocketAddress(port));
		//打开筛选器
		selector=Selector.open();
		
		// 将选择器绑定到监听信道,只有非阻塞信道才可以注册选择器.并在注册过程中指出该信道可以进行Accept操作,返回key
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		System.out.println("Server start ->"+port);
	}
	
	//NIOServer的监听事件
	public void listen() throws IOException{
		while(true){
			selector.select();
			Set<SelectionKey> selectionKeys=selector.selectedKeys();
			Iterator<SelectionKey> itetor=selectionKeys.iterator();
			while(itetor.hasNext()){
				//负责多线程并发的安全的key
				SelectionKey selectionKey=itetor.next();
				itetor.remove();
				//业务逻辑
				handleKey(selectionKey);
			}
		}
	}
	
	
	//业务逻辑
	public void handleKey(SelectionKey selectionKey) throws IOException{
		//服务端监听通道
		ServerSocketChannel server=null;
		SocketChannel client=null;
		String reciveText;
		String sendText;
		int count=0;
		if(selectionKey.isAcceptable()){
			//服务端接收客户端信息
			server=(ServerSocketChannel)selectionKey.channel();
			client=server.accept();
			client.configureBlocking(false);
			client.register(selector, selectionKey.OP_READ);
		}else if(selectionKey.isReadable()){
			//服务端读取客户端信息
			client =(SocketChannel)selectionKey.channel();
			count =client.read(receivebuffer);
			if(count>0){
				reciveText =new String(receivebuffer.array(),0,count);
				System.out.println("服务端接收到客户端的信息:"+reciveText);
				client.register(selector,selectionKey.OP_WRITE);
			}
		}else if (selectionKey.isWritable()){
			//服务端发送数据给客户端
			sendbuffer.clear();
			client=(SocketChannel)selectionKey.channel();
			sendText="mag send to client:"+flag++;
			sendbuffer.put(sendText.getBytes());
			sendbuffer.flip();
			client.write(sendbuffer);
			System.out.println("服务端发送数据给客户端:"+sendText);
			
		}
		
	}
	
	public static void main(String[] args) throws IOException {
		int port =7080;
		NIOServer server =new NIOServer(port);
		server.listen();
	}
	
	
	
}




服务端代码:

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.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOClient {
	private static  int flag =1;
	private static int blockSize=4096;
	private static ByteBuffer sendbuffer =ByteBuffer.allocate(blockSize);//发送数据缓冲区
	private static  ByteBuffer receivebuffer =ByteBuffer.allocate(blockSize);//接收数据缓冲区
	
	//Socket地址:ip+端口
	private final static InetSocketAddress serverAddress=new InetSocketAddress("127.0.0.1",7080);
	
	public static void main(String[] args) throws IOException {
		//打开通道
		SocketChannel socketChannel=SocketChannel.open();
		//通道设置成非阻塞模式
		socketChannel.configureBlocking(false);
		//打开筛选器
		Selector selector =Selector.open();
		//注册选择器
		socketChannel.register(selector, SelectionKey.OP_CONNECT);
		socketChannel.connect(serverAddress);
		
		Set<SelectionKey> selectionKeys;
		Iterator<SelectionKey> iterator;
		SelectionKey selectionKey;
		SocketChannel client;
		String receiveTest;
		String sendText;
		int count=0;		
		while(true){
			selectionKeys =selector.selectedKeys();
			iterator=selectionKeys.iterator();
			while(iterator.hasNext()){
				selectionKey=iterator.next();
				if(selectionKey.isConnectable()){
					System.out.println("client connect");
					client =(SocketChannel)selectionKey.channel();
					if(client.isConnectionPending()){
						client.finishConnect();
						System.out.println("客户端完成连接操作!");
						sendbuffer.clear();
						sendbuffer.put("Hello,Server".getBytes());
						sendbuffer.flip();
						client.write(sendbuffer);
					}
					client.register(selector, SelectionKey.OP_READ);
					
				}if(selectionKey.isReadable()){
						client=(SocketChannel)selectionKey.channel();
						receivebuffer.clear();
						count=client.read(receivebuffer);
						if(count>0){
							receiveTest =new String(receivebuffer.array(),0,count);
							System.out.println("客户端接收到服务端的数据:"+receiveTest);
							client.register(selector,SelectionKey.OP_WRITE);
							
						}
				}if(selectionKey.isWritable()){
					sendbuffer.clear();
					client=(SocketChannel)selectionKey.channel();
					sendText="Msg from client--->"+flag++;
					sendbuffer.put(sendText.getBytes());
					sendbuffer.flip();
					client.write(sendbuffer);
					System.out.println("客户端发送方数据给服务端:"+sendText);
					client.register(selector, SelectionKey.OP_READ);
					
				}
				}
			
			selectionKeys.clear();
			}
		}
	}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值