1. 程式人生 > >SocketChannel類(用於阻塞或非阻塞式傳輸資料) 建立SocketChannel要使用SocketChannel類的靜態工廠方法。 SocketChannel open():建立未連線的

SocketChannel類(用於阻塞或非阻塞式傳輸資料) 建立SocketChannel要使用SocketChannel類的靜態工廠方法。 SocketChannel open():建立未連線的

轉自:http://blog.csdn.net/wolfdrake/article/details/37921441

SocketChannel類(用於阻塞或非阻塞式傳輸資料)

建立SocketChannel要使用SocketChannel類的靜態工廠方法。

SocketChannel open():建立未連線的SocketChannel.

SocketChannel open(SocketAddress remote):建立連線到remote埠的SocketChannel.

新建立的SocketChannel為阻塞式的。

SelectableChannel configureBlocking(boolean block):將本SocketChannel設定為阻塞或非阻塞式並返回。

boolean isBlocking():返回本SocketChannel是否處於阻塞模式。

boolean connect(SocketAddress remote):連線到remote埠,是否是阻塞式連線取決於SocketChannel的設定。函式返回時,若已連線成功則返回true.

boolean finishConnect(SocketAddress);非阻塞connect返回false之後,可以呼叫這個函式完成連線,這個函式是否阻塞取決於SocketChannel的設定。函式返回時,若已連線成功則返回true.如果在呼叫函式之前就已經成功連線了,則函式什麼都不做,直接返回true.

boolean isConnected():SocketChannel已連線時返回true.

boolean isConnectionPending():如果SocketChannel正在嘗試連線,則返回true.

Socket socket():返回此SocketChannel的socket.

int read(ByteBuffer dst):將dst從position填充至limit,讀到流末尾會停下來,非阻塞讀時一旦沒得可讀也會停下來,是否阻塞取決於SocketChannel的設定。返回實際讀到的位元組數n,同時dst的position會加n.如果讀之前socket的輸入流就位於流末尾,則返回-1.如果函式呼叫時已經有一個執行緒正在從輸入流裡讀,則本執行緒會等到它讀完之後才開始讀。

int write(ByteBuffer src):將src從position到limit的資料寫入socket的輸出流,非阻塞寫時一旦底層的輸出緩衝區滿了就會停下來,是否阻塞取決於SocketChannel的設定。返回實際寫入的位元組數n,同時src的position會加n.如果函式呼叫時已經有一個執行緒正在往輸出流裡寫,則本執行緒會等到它寫完之後才開始寫。

int validOps():返回SocketChannel可能產生的事件,即SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE(連線成功、可讀、可寫)。

SelectionKey register(Selector sel, int ops, Object att):要求偵聽者sel幫忙偵聽ops事件,返回這個契約。契約可以帶一個附件att,若att為null則不帶附件。

SelectionKey register(Selector sel, int ops):同上,相當於att等於null,不帶附件。

SelectionKey keyFor(Selector sel):返回與偵聽者sel定下的契約。如果尚未定下契約,則返回null.

boolean isRegistered():如果本SocketChannel現在正和某偵聽者有契約,則返回true.尚未和任何偵聽者定下過契約,或全部契約都已經解除,這兩種情況都返回false.

void close():關閉本SocketChannel,並解除其一切契約。

boolean isOpen():如果本SocketChannel處於開啟狀態,則返回true.

ServerSocketChannel類(用於阻塞或非阻塞式偵聽連線)

建立ServerSocketChannel要使用ServerSocketChannel類的靜態工廠方法。

ServerSocketChannel open():建立未繫結的ServerSocketChannel.

新建立的ServerSocketChannel是阻塞式的。

ServerSocket socket():返回此ServerSocketChannel的serversocket.

SocketChannel accept():偵聽連線請求,阻塞模式下會一直等待直到出現請求,非阻塞模式下如果沒有請求就直接返回null.

int validOps():返回ServerSocketChannel可能產生的事件,即SelectionKey.OP_ACCEPT(有連線請求)。

SelectableChannel configureBlocking(boolean block),boolean isBlocking(),SelectionKey register(Selector sel, int ops, Object att),SelectionKey register(Selector sel, int ops),SelectionKey keyFor(Selector sel),boolean isRegistered(),void close(),boolean isOpen():參見SocketChannel類的相應函式。

Selector類(偵聽器類)

1. 偵聽者維護三個契約集合:all-keys,selected-keys,cancelled-keys.

偵聽者建立時,三個集合都是空的。每締結一個契約,就把它新增到all-keys中。呼叫select或selectNow函式時會把all-keys中發生了事件的契約也新增到selected-keys中。一個契約被解除時,會被新增到cancelled-keys中,下次呼叫select或selectNow函式時就會從全部三個集合中被刪去。可見,後兩個集合始終是all-keys的子集。

2. 建立偵聽器要採用Selector類的靜態工廠方法。

Selector open():建立偵聽器。偵聽器被建立後直接就是開著的。

boolean isOpen():如果偵聽器是開著的,則返回true.

Set<SelectionKey> keys():返回all-keys契約集。不得對這個集合進行修改。

Set<SelectionKey> selectedKeys():返回selected-keys契約集。對這個集合只能刪除契約,不得做其它修改。

Selector wakeup():給偵聽器吃“提神藥”(見select函式)並返回。

int select(long timeout):將all-keys中發生了事件的契約也新增到selected-keys中,如果沒有一個發生了事件,則阻塞等待,至多等待timeout毫秒,而且只要吃了提神藥,就會立刻退出阻塞,並消耗掉全部的藥效。最終返回新增契約的個數。如果timeout為0,則禁用超時。

可見,如果程序A阻塞於偵聽器s的select函式,程序B呼叫s.wakeup(),則程序A立刻退出阻塞。

如果程序B呼叫一次或多次s.wakeup(),然後程序A呼叫s的select函式,則select會立即返回。接下來如果沒有程序呼叫s.wakeup(),則再次select的話又會阻塞。

int select():同上,只不過禁用超時。

int selectNow():同樣是將all-keys中發生了事件的契約也新增到selected-keys中,返回新增的個數,但是是非阻塞式的,沒有就返回0.

void close():給偵聽器吃提神藥,解除其一切契約,然後將它關閉。

SelectionKey類(契約類)

Object attach(Object ob):設定契約的附件為ob。如果ob為null則表示不要附件。

Object attachment():返回本契約的附件。

SelectableChannel channel():返回締結本契約的Channel.

Selector selector():返回締結本契約的偵聽者。

SelectionKey interestOps(int ops):設定偵聽者所要偵聽的事件,並返回本契約。SelectionKey.OP_READ,SelectionKey.OP_WRITE,SelectionKey.OP_CONNECT,SelectionKey.OP_ACCEPT,分別表示Channel的輸入流有資料可讀、輸出流有空位可寫、連線成功、有連線請求事件。多個事件用位或(|)來組合。

int interestOps():返回偵聽者所要偵聽的事件。

int readyOps():返回已經發生的事件。

boolean isReadable/isWritable/isConnectable/isAcceptable():如果Channel的可讀/可寫/連線成功/有連線請求事件已發生,則返回true.

void cancel():解除本契約。

isValid():返回本契約當前是否有效(尚未被解除)。