ServerSocketChannel的用法詳解

2021-07-02 18:27:08 字數 2821 閱讀 5458

在用nio通訊的過程我用以下情景給你模擬: 

1. 學校(serversocketchannel)

2。 學校教務處(selector)

3。 老師 (serversocket )

4。 學生 (socketchannel)

5。 員工號/學生號(selectionkey)

學校:相當於我們的網路應用程式,一旦學校啟動,學校就不停止,不斷執行,直到學期結束;

要啟動學校就要:

serversocketchannel ssc= serversocketchannel.open();//新建nio通道

ssc.configureblocking( false );//使通道為非阻塞

老師: 相當於服務端的socket,乙個老師對應多個學生,多個學生向老師請教,老師會一一做出回答。而學校要正常運營當然當不了老師,所以在開學之前,必須先聘請專業的老師來任教

serversocket ss = ssc.socket();//建立基於nio通道的socket連線

//新建socket通道的埠

ss.bind(new inetsocketaddress("127.0.0.1",serverport));

學校教務處: 老師都有了,但是需要有部門對老師和學生做統一的管理, 如果你去乙個學校找乙個人,實在是找不到,你可以告訴教務處,那個人是學生還是老師,是老師的話員工編號老師姓名的多少,是學生的話學號和姓名是多少,教務處就會找到告訴你他在**。

//將nio通道選繫結到擇器,當然繫結後分配的主鍵為skey

selectionkey skey = ssc.register( selector, selectionkey.op_accept );

ssc註冊了選擇器後,其下的老師serversocket就也入了員工冊了。所以老師的編號就是skey

學生: 學校、老師、教務處都有了,現在就可以招生了!

如果有學生來報名:

while(true)

set selectedkeys = selector.selectedkeys();//獲取通道內關心事件的集合 ,這裡的集合就是老師和學生的編號集合,如果key是學生的,那就是老學生來問問題,如果key是老師的,那就是招生辦的老師帶著乙個新生來註冊

iterator it = selectedkeys.iterator();

while (it.hasnext())

.....

} 既然有學生來報告,那有兩種可能,一種是招生老師帶著新生來註冊的,一種是老生來問問題的。

上面的while (it.hasnext()) 體可以這樣寫:

while (it.hasnext()) else

//讀客戶端資料的事件,此時有客戶端發資料過來,客戶端事件 這是老學生來問問題了。

if((key.readyops() & selectionkey.op_read)== selectionkey.op_read)

echobuffer.flip();

system.out.println("limet:"+echobuffer.limit());

byte content = new byte[echobuffer.limit()];

echobuffer.get(content);

string result=new string(content);

dopost(result,sc); //相應老師會去做回答的,細節自己去寫吧

echobuffer.clear();

it.remove(); //任務完成,記得上面也是一樣,要remove掉,否則下一次又來一次任務,就死迴圈了

} }catch(exception e){} } }

補充你的補充:

ssc.register( selector, selectionkey.op_accept );

這個方法是把ssc註冊繫結到選擇器selector 這樣下次你想找ssc或者判斷乙個物件是不是ssc就可以通過selector來查詢,查詢是通過判斷ssc的key得到的。

至於第二個引數selectionkey.op_accept 你可以理解成ssc的key型別或者操作許可權

如果 ssc是學校老師,那麼繫結成功後 老師就擁有了op_accept的許可權或者說他的key型別是selectionkey.op_accept

accept是接受的意思,這是不是很像socket程式設計裡的 accept()方法呢? 是的,沒錯,我們正是通過這個引數給了老師招生和帶學生來註冊的許可權。

而學生呢?

他擁有的許可權為selectionkey.op_read 表示有收發讀取訊息的許可權,即問問題的許可權,因此他不能幫別的學生註冊。

所以你回到上面仔細看看while結構體裡面做了判斷如下:

if ((key.readyops() & selectionkey.op_accept) == selectionkey.op_accept) 很明顯,擁有accept許可權的人只可能是老師,那老師有什麼事會找教務處? 那肯定就是他是招生辦的,招到乙個學生來報名來註冊了。

然後,馬上給這個新連上來的客戶端分配了乙個key

selectionkey newkey = sc.register( selector,

selectionkey.op_read ); 看,這裡只給他op_read,而不是accept哦

另乙個if

else

if((key.readyops() & selectionkey.op_read)== selectionkey.op_read){

//很明顯,這是這學生,因為所有帶op_read的人都是前面由招生辦老師帶過來註冊過的。

nginx limit req zone用法詳解

nginx可以使用ngx http limit req module模組的limit req zone指令進行限流訪問,防止使用者惡意攻擊刷爆伺服器。ngx http limit req module模組是nginx預設安裝的,所以直接配置即可。首先,在nginx.conf檔案中的http模組下配置...

oracle case when 語句的用法詳解

1.case when 表示式有兩種形式 複製 如下 簡單case函式 case when 1 then 男 when 2 then 女 else 其他 end case搜尋函式 case whe程式設計客棧n 1 then 男 when 2 then 女 else 其他 end 2.case wh...

Linux shell 的 test 命令用法詳解

基本格式 test expression expression為test命令構造的表示式。這裡expression是test命令可以理解的任何有效表示式,該簡化格式將是讀者可能會踫見的最常用格式 返回值 test命令或者返回0 真 或者返回1 假 test可理解的表示式型別分為四類 1 判斷表示式 ...