1. 程式人生 > >java nio 實現客戶端與服務端讀寫

java nio 實現客戶端與服務端讀寫

剛開始寫,有待後續完善

服務端程式碼:

package com.geng.test3;

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

public class Server {
	private static Selector selector ;

	public  static void init() throws IOException{
		selector = Selector.open();
		ServerSocketChannel ssc = ServerSocketChannel.open();
		ssc.configureBlocking(false);
		ssc.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8099));
		ssc.register(selector, SelectionKey.OP_ACCEPT);
	}
	
	public static void listen() throws IOException{
		while(true){
			int select = selector.select();
			if(select == 0){
				continue;
			}
			Set<SelectionKey> selectedKeys = selector.selectedKeys();
			Iterator<SelectionKey> it = selectedKeys.iterator();
			while(it.hasNext()){
				SelectionKey key = it.next();
				// 由於select操作只管對selectedKeys進行新增,所以key處理後我們需要從裡面把key去掉  
				it.remove();
				if(key.isAcceptable()){
					ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
					// 得到與客戶端的套接字通道  
					SocketChannel channel = serverChannel.accept();
					channel.configureBlocking(false);
					// 同樣將於客戶端的通道在selector上註冊,,可以通過key獲取關聯的選擇器
					channel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
				}else if(key.isReadable()){
					read(key);
					 // 改變自身關注事件,可以用位或操作|組合時間  
					key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
				}else if(key.isWritable()){
					write(key);
					 // 改變自身關注事件,可以用位或操作|組合時間  
					key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
				}
			}
		}
	}

	private static void write(SelectionKey key) throws IOException {
		SocketChannel channel = (SocketChannel) key.channel();
		channel.write(ByteBuffer.wrap("server write".getBytes()));
		
	}

	private static void read(SelectionKey key) throws IOException {
		SocketChannel channel = (SocketChannel) key.channel();
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		int count = channel.read(buffer);
		byte[] bytes = new byte[count];
		buffer.flip();
		buffer.get(bytes);
		//System.out.println(new String(bytes));
		
	}
	
	public static void main(String[] args) throws IOException {
		init();
		listen();
	}
}

客戶端程式碼:
package com.geng.test3;

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

public class Client {

	private static Selector selector;
	
	public static void init() throws IOException{
		selector = Selector.open();
		SocketChannel sc = SocketChannel.open();
		sc.configureBlocking(false);
		sc.connect(new InetSocketAddress(InetAddress.getLocalHost(), 8099));
		
		sc.register(selector, SelectionKey.OP_CONNECT);
	}
	
	public static void listen() throws IOException{
		while(true){
			selector.select();
			Set<SelectionKey> selectedKeys = selector.selectedKeys();
			Iterator<SelectionKey> it = selectedKeys.iterator();
			while(it.hasNext()){
				SelectionKey key = it.next();
				it.remove();
				
				if(key.isConnectable()){
					SocketChannel channel = (SocketChannel) key.channel();
					if(channel.finishConnect()){
						channel.configureBlocking(false);
						channel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
					}
				}else if(key.isReadable()){
					read(key);
					 // 改變自身關注事件,可以用位或操作|組合時間  
					key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
				}else if(key.isWritable()){
					write(key);
					 // 改變自身關注事件,可以用位或操作|組合時間  
					key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
				}
				
			}
		}
	}
	
	private static void write(SelectionKey key) throws IOException {
		SocketChannel channel = (SocketChannel) key.channel();
		channel.write(ByteBuffer.wrap("server write".getBytes()));
		
	}

	private static void read(SelectionKey key) throws IOException {
		SocketChannel channel = (SocketChannel) key.channel();
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		int count = channel.read(buffer);
		byte[] bytes = new byte[count];
		buffer.flip();
		buffer.get(bytes);
		System.out.println(new String(bytes));
		
	}
}