簡單SocketChannel 服務端和客戶端連接


服務端代碼:

public static void main(String[] args) throws Exception 
	{
		// 創建選擇器  
		Selector selector = Selector.open();
		// 打開監聽信道  
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		// 與本地端口綁定  
		serverSocketChannel.socket().bind(new InetSocketAddress(9999));
		// 設置爲非阻塞模式 
		serverSocketChannel.configureBlocking(false); 
		// 將選擇器綁定到監聽信道,只有非阻塞信道纔可以註冊選擇器.並在註冊過程中指出該信道可以進行Accept操作  
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		
		while (true) 
		{
			// 等待某信道就緒
			int selectInt = selector.select();
			if (selectInt == 0)
				continue;
			// 取得迭代器.selectedKeys()中包含了每個準備好某一I/O操作的信道的SelectionKey
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while (iterator.hasNext())
			{
				SelectionKey selectionKey = iterator.next();
				// 有客戶端連接請求時 
				if (selectionKey.isAcceptable())
					handleAccept(selectionKey);
				// 從客戶端讀取數據  
				if (selectionKey.isReadable())
					handleRead(selectionKey);
				// 向客戶端發送數據
			    if (selectionKey.isWritable())
					handleWrite(selectionKey);
				iterator.remove();
			}
		}
	}
	
	
	public static void handleAccept(SelectionKey selectionKey) throws Exception
	{
		// 返回創建此鍵的通道,接受客戶端建立連接的請求,並返回 SocketChannel 對象
		ServerSocketChannel ServerSocketChannel = (ServerSocketChannel)selectionKey.channel();
		SocketChannel clientChannel = ServerSocketChannel.accept();
		// 非阻塞式 
		clientChannel.configureBlocking(false);
		// 註冊到selector
		clientChannel.register(selectionKey.selector(), SelectionKey.OP_READ);
		
		sendInfo(clientChannel, "連接服務器成功!");
		System.err.println("client IP :" + clientChannel.socket().getRemoteSocketAddress());
	}
	
	public static void handleRead(SelectionKey key) throws Exception
	{
		SocketChannel channel = (SocketChannel) key.channel();
		String msg = "";
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while(channel.read(buffer) > 0)
		{
			buffer.flip();
			while(buffer.hasRemaining())
				msg += new String(buffer.get(new byte[buffer.limit()]).array());
			buffer.clear();
		}  
		
        System.err.println("收到客戶端消息:"+msg);
        
        sendInfo(channel, "服務端消息test!");
	}
	
	public static void handleWrite(SelectionKey key)
	{
		System.out.println("服務端發送信息!");
	}
	
	public static void sendInfo(SocketChannel clientChannel, String msg) throws Exception
	{
		// 向客戶端發送連接成功信息
		clientChannel.write(ByteBuffer.wrap(msg.getBytes()));
	}

客戶端代碼:

public static void main(String[] args) throws Exception 
	{
		// 創建選擇器  
		Selector selector = Selector.open();
		SocketChannel socketChannel = SocketChannel.open();
		socketChannel.configureBlocking(false);
		socketChannel.connect(new InetSocketAddress("localhost", 9999));
		socketChannel.register(selector, SelectionKey.OP_CONNECT); 
		
		while (true) 
		{
			int selectInt = selector.select();
			if (selectInt == 0)
				continue;
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while(iterator.hasNext())
			{
				SelectionKey key = iterator.next();
				if (key.isConnectable())
					handleConnect(key);
				if (key.isReadable())
					handleRead(key);
				if (key.isWritable())
					handleWrite(key);
				iterator.remove();
			}
		}
		
	}
	
	public static void handleConnect(SelectionKey key) throws Exception
	{
		SocketChannel channel = (SocketChannel) key.channel();
		if (channel.isConnectionPending())
			channel.finishConnect();
		channel.configureBlocking(false);
		channel.register(key.selector(), SelectionKey.OP_READ);
		
		sendInfo(channel, "客戶端測試!");
	}
	
	public static void handleRead(SelectionKey key) throws Exception
	{
		SocketChannel channel = (SocketChannel) key.channel();
		String msg = "";
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while(channel.read(buffer) > 0)
		{
			buffer.flip();
			while(buffer.hasRemaining())
				msg += new String(buffer.get(new byte[buffer.limit()]).array());
			buffer.clear();
		}   
		
        System.err.println("收到服務端消息:"+msg);
	}
	
	public static void handleWrite(SelectionKey key) throws Exception
	{
		System.err.println("客戶端寫數據!");
	}
	
	public static void sendInfo(SocketChannel clientChannel, String msg) throws Exception
	{
		// 向客戶端發送連接成功信息
		clientChannel.write(ByteBuffer.wrap(msg.getBytes()));
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章