Java NIO筆記(七):Socket通道

一、Socket通道介紹

        Socket通道即套接字通道,是一種基於TCP連接協議傳輸數據的通道。Socket通道可以以分阻塞模式運行,並且可以被Reactor設計模式使用,因爲Socket通道是可供選擇的,其繼承SelectableChannel類。

        非阻塞I/O是複雜的、高性能的程序構建的基礎。

        使用NIO的Socket通道就沒有必須像舊的Socket一樣爲每個Socket創建一個線程,避免了N個線程之間切換上下文的性能開銷,使用NIO的Socket通道可以一個或幾個線程就可以管理成百上千個已連接的Socket,並且性能消耗非常小。

  • ServerSocketChannel:負責監聽某個端口,等待客戶端Socket連接進來
  • SocketChannel:可以理解爲一對一對使用,客戶端使用SocketChannel連接服務器,服務器也會有個對等的SocketChannel
  • DatagramChannel:基於UDP發送數據報

        所有的Socket通道類被創建後都有一個關聯的Socket;但是使用舊的方法直接創建Socket並不會關聯一個通道,雖然它們有getChannel()方法,但是這個方法會返回null。

二、ServerSocketChannel

        ServerSocketChannel有如下方法可供使用:

  • open():打開一個ServerSocketChannel,用於創建ServerSocketChannel
  • validOps():返回SelectionKey.OP_ACCEPT,一般用不到,可用於驗證註冊到選擇器時指定的興趣是否位OP_ACCEPT
  • socket():返回與通道關聯的ServerSocket
  • accept():等待接受一個Socket連接,非阻塞模式下可能返回null
		//打開一個ServerSocketChannel
		ServerSocketChannel ssc = ServerSocketChannel.open();
		//將通道關聯的ServerSocket綁定65535端口
		//jdk1.7之後可以ssc.bind(new InetSocketAddress(65535))
		ssc.socket().bind(new InetSocketAddress(65535));
		//設置非阻塞模式
		ssc.configureBlocking(false);

三、SocketChannel

        SocketChannel有如下方法可供使用:

  • open():打開一個SocketChannel
  • open(SocketAddress remote):同open(),並指定連接服務器地址
  • validOps():返回SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT,作用同ServerSocketChannel的validOps()
  • socket():返回通道關聯的Socket
  • isConnected():檢查是否已連接,返回true or false
  • isConnectionPending():檢查是否處於請求連接狀態
  • connect(SocketAddress remote):連接指定地址服務器
  • finishConnect():強制完成連接,完成連接則返回true,返回false
  • read(ByteBuffer dst):將通道的數據讀到ByteBuffer
  • read(ByteBuffer[] dsts):將通道數據分散讀到ByteBuffer數組
  • read(ByteBuffer[] dsts, int offset, int length):將通道數據分散讀到ByteBuffer數組,並指定讀取數據的開始位置和讀取的長度
  • write(ByteBuffer src):將字節緩衝區的數據寫入通道
  • write(ByteBuffer[] srcs):將分散的字節緩衝區的數據聚集寫入通道
  • write(ByteBuffer[] srcs, int offset, int length):同上一個方法,並指定寫入數據的開始位置和長度
		SocketChannel sc = SocketChannel.open();
		sc.configureBlocking(false);
		sc.connect(new InetSocketAddress("127.0.0.1", 65535));
		//輪詢直到成功連接爲止
		while(!sc.isConnected()){
			
		}

四、DatagramChannel

  • open():打開一個DatagramChannel
  • validOps():返回SelectionKey.OP_READ | SelectionKey.OP_WRITE
  • socket():返回關聯的DatagramSocket
  • isConnected():是否已連接
  • connect(SocketAddress remote)》:連接某個地址
  • disconnect():斷開連接
  • receive(ByteBuffer dst):接收數據,從通道讀入緩衝區
  • send(ByteBuffer src, SocketAddress target):將緩衝區的數據發送到指定網絡地址
  • read(ByteBuffer dst)
  • read(ByteBuffer[] dsts)
  • read(ByteBuffer[] dsts, int offset, int length)
  • write(ByteBuffer src)
  • write(ByteBuffer[] srcs)
  • write(ByteBuffer[] srcs, int offset, int length)

        這麼需要說明下,DatagramChannel提供了connect方法,別被這樣的方法套住了,DatagramSocket是基於UDP的,UDP是無連接的,connection方法只是綁定某個地址,只能從這個地址接收數據或發送數據到這個地址。

        這節主要介紹3個Socket通道的API,讀取若想感受下他們的實際的使用,可以到下面兩個地址下載實戰源碼:

  • Java簡單版飛鴿傳書:http://download.csdn.net/detail/abc_key/7497543
  • Java簡單聊天室:http://download.csdn.net/detail/abc_key/7459723
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章