Socket通道類:DatagramChannel,SocketChannel,ServerSocketChannel
DatagramChannel和SocketChannel實現了ReadableByteChannel 和 WritableByteChannel接口,而ServerSocketChannel沒實現
socket類有Socket,ServerSocket,DatagramSocket
socket和socket通道之間的關系:
1 socket位于java.net包下,socket通道位于java.nio
2 Socket通道被創建的時候都會創建一個對等的Socket實例
3 通道的socket()可以調用socket,socket的getChannel()可以調用通道
4 Socket通道都有對應的Socket對象,但直接定義的Socket對象是沒有對應的通道
5 Socket通道委派協議操作給對應的Socket對象
要把一個Socket通道置為非阻塞模式,就要依靠所有Socket通道類的父類SelectableChannel
ServerSocketChannel是一個基于通道的Socket監聽器,因為增加了通道語意,所以可以在非阻塞模式下運行。
非阻塞模式下,沒有連接傳入時,ServerSocketChannel.accept()返回null
SocketChannel使用最頻繁
Socket,SocketChannel類封裝點對點,有序的網絡連接,類似于TCP/IP網絡連接
Socket是面向流的
ServerSocketChannel只負責監聽傳入的連接,創建新的SocketChannel,它自身從不傳輸數據
socket類有Socket,ServerSocket,DatagramSocket
socket和socket通道之間的關系:
1 socket位于java.net包下,socket通道位于java.nio
2 Socket通道被創建的時候都會創建一個對等的Socket實例
3 通道的socket()可以調用socket,socket的getChannel()可以調用通道
4 Socket通道都有對應的Socket對象,但直接定義的Socket對象是沒有對應的通道
5 Socket通道委派協議操作給對應的Socket對象
要把一個Socket通道置為非阻塞模式,就要依靠所有Socket通道類的父類SelectableChannel
ServerSocketChannel是一個基于通道的Socket監聽器,因為增加了通道語意,所以可以在非阻塞模式下運行。
ServerSocketChannel沒有bind方法,只能通過其對應的ServerSocket來實現
ServerSocketChannel和其對應的ServerSocket都有accept()方法:
ServerSocketChannel.accept() 返回SocketChannel對象,SocketChannel中包含對應的Socket
ServerSocket.accept() 阻塞并返回一個Socket對象
非阻塞模式下,沒有連接傳入時,ServerSocketChannel.accept()返回null
SocketChannel使用最頻繁
Socket,SocketChannel類封裝點對點,有序的網絡連接,類似于TCP/IP網絡連接
Socket是面向流的
SocketChannel扮演客戶端發起一個監聽服務器的連接,直到連接成功,才能收到數據,并且只從連接到的地址接收
SocketChannel的connect()方法是阻塞式的,同其對應Scoket的connect()方法一樣
在非阻塞模式下調用SocketChannel的finishConnect()方法會返回的結果:
1 connect()方法沒調用,產生NoConnectionPendingException異常
2 連接正在建立,尚未完成,立即返回false
3 非阻塞模式下調用connect()后,SocketChannel回到阻塞模式,立即返回false
4 連接已建立后,SocketChannel內部狀態會更新為已連接狀態,finishConnect()方法會返回true,SocketChannel就可以開始傳輸數據了
DatagramChannel對應DatagramSocket對象,模擬包導向的無連接協議UDP/IP
在非阻塞模式下調用SocketChannel的finishConnect()方法會返回的結果:
1 connect()方法沒調用,產生NoConnectionPendingException異常
2 連接正在建立,尚未完成,立即返回false
3 非阻塞模式下調用connect()后,SocketChannel回到阻塞模式,立即返回false
4 連接已建立后,SocketChannel內部狀態會更新為已連接狀態,finishConnect()方法會返回true,SocketChannel就可以開始傳輸數據了
DatagramChannel對應DatagramSocket對象,模擬包導向的無連接協議UDP/IP
DatagramSocket
每個數據報Datagram都包含自己的地址DatagramChannel可以發送Datagram到不同的地址,同樣也可以接收不同地址的Datagram
基于包的吞吐量比基于流的高很多,因為互聯網基礎設施就是包導向的
TCP這樣面向流的協議會產生巨大的開銷,并且不能適用所有的情形
選擇DatagramSocket而不是流Socket的前提:
1 程序可以承受數據丟失和無序數據
2 發送后不需要知道對方是否已經接收,即fire and forget
3 數據吞吐量比可靠性更重要
4 同時發送數據給多個接收者
5 包導向更適合現在的任務
基于包的吞吐量比基于流的高很多,因為互聯網基礎設施就是包導向的
TCP這樣面向流的協議會產生巨大的開銷,并且不能適用所有的情形
選擇DatagramSocket而不是流Socket的前提:
1 程序可以承受數據丟失和無序數據
2 發送后不需要知道對方是否已經接收,即fire and forget
3 數據吞吐量比可靠性更重要
4 同時發送數據給多個接收者
5 包導向更適合現在的任務