天天看點

Java NIO學習筆記六 SocketChannel 和 ServerSocketChannelJava NIO SocketChannelJava NIO ServerSocketChannel

Java NIO SocketChannel

  Java NIO SocketChannel是連接配接到TCP網絡socket(套接字)的通道。Java NIO相當于Java Networking的socket(套接字)。有兩種建立

SocketChannel的方法

  1. 打開

    SocketChannel

    并連接配接到網際網路上的某個伺服器。
  2. 當一個連接配接接入到一個

    ServerSocketChannel時,SocketChannel就會被建立

打開一個SocketChannel

  打開一個

SocketChannel

SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress(“http://jenkov.com”,80));      

關閉SocketChannel

  使用完SocketChannel後,可以

通過調用

SocketChannel的close()

方法,将其關閉。

代碼展示:

socketChannel.close();        

從SocketChannel讀取資料

  要從

SocketChannel

您那裡讀取資料,可以調用

read()

方法。

代碼:

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = socketChannel.read(buf);      

首先:進行

Buffer

配置設定,從SocketChannel中讀取的資料到

Buffer中

然後:調用SocketChannel的read()

方法。将資料從

SocketChannel中讀

Buffer

。傳回值是int,表示有多少位元組資料被讀入到Buffer緩存中。如果傳回-1,則到達端到端(連接配接已關閉)。

資料寫入SocketChannel

  SocketChannel

使用

SocketChannel的write()

 方法來寫入資料,該方法使用

Buffer做

參數。

代碼展示:

String newData =“要寫入檔案的新字元串...”+ System.currentTimeMillis();

ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());

buf.flip();

while(buf.hasRemaining()){
    channel.write(buf);
}      

  注意

SocketChannel.write()

在while循環中如何調用該方法。不能保證

write()

方法寫入SocketChannel的位元組數。是以,我們重複調用

write()

,直到

Buffer

沒有位元組可以寫入。

非阻塞模式

  您可以将SocketChannel設定為非阻塞模式。在非阻塞模式下,你可以以異步方式調用

connect()

read()

write()方法

connect()

  如果

SocketChannel

是非阻塞模式,并且您調用

connect()

,方法可能會在建立連接配接之前傳回。要确定連接配接是否建立,可以調用

finishConnect()

方法,如下所示:

socketChannel.configureBlocking(假);
socketChannel.connect(new InetSocketAddress(“http://jenkov.com”,80));

while(!socketChannel.finishConnect()){
    //做其他的事情    
}      

write()

  在非阻塞模式下,

write()

方法在不寫任何資料的情況下可以傳回。是以,你需要在循環中調用write()方法。代碼同上。

read()

  在非阻塞模式下,

read()

方法可以在沒有讀取任何資料的情況下傳回。是以,您需要注意傳回的值

int

,這表示讀取了多少個位元組。

具有選擇器的非阻塞模式

  這種非阻塞模式的

SocketChannel

效果要比

Selector好點

。通過使用

Selector

注冊一個或一個以上

SocketChannel

,你可以通路已經準備讀、寫通道的

Selector。

Java NIO ServerSocketChannel

  Java NIO ServerSocketChannel是可以監聽接入TCP連接配接的通道,就像

ServerSocket

的Java标準網絡一樣。

ServerSocketChannel類

位于

java.nio.channels

包中。

java代碼展示:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));

while(true){
    SocketChannel socketChannel =
            serverSocketChannel.accept();

    //用socketChannel做一些事情...
}      

開啟ServerSocketChannel

  通過調用

ServerSocketChannel的open()

 方法,你可以打開一個

ServerSocketChannel

代碼展示:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();      

關閉ServerSocketChannel

  

通過調用

ServerSocketChannel的close()

 方法來關閉ServerSocketChannel。這是怎麼樣的樣子:

serverSocketChannel.close();      

監聽接入的連接配接

  通過調用

ServerSocketChannel的accept()

 方法來監聽傳接入連接配接。當該

accept()

方法傳回時,它傳回

SocketChannel

一個傳入連接配接。是以,

accept()

方法阻塞直到有連接配接介入。

  我們通常不會對單個連接配接進行監聽,是以您可以在

accept()

内部調用一個循環,來監聽多個接入的連接配接。

代碼展示:

while(true){
    SocketChannel socketChannel = serverSocketChannel.accept();

    //用socketChannel做一些事情...
}      

非阻塞模式

  ServerSocketChannel

可以設定為非阻塞模式。在非阻塞模式下,

accept()

方法立即傳回,如果沒有連接配接,則傳回null。是以,您必須檢查傳回值 

SocketChannel

是否為空。

代碼展示:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket()。bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);

while(true){
    SocketChannel socketChannel =
            serverSocketChannel.accept();

    if(socketChannel!= null){
        //用socketChannel做一些事情...
        }
}      

轉載于:https://www.cnblogs.com/kuoAT/p/7016905.html