[Java聊天室server]實戰之三 接收循環

前言

學習不論什麼一個稍有難度的技術,要對其有充分理性的分析,以後果斷作出決定---->也就是人們常說的「多謀善斷";本系列儘管涉及的是socket相關的知識。但學習以前,更想和廣大程序猿分享的是一種心境微笑:學習是一個按部就班的過程,心態應該隨時調節,保持戒驕戒躁的狀態。html

比方近期在看網易公開課MIT《算法導論》,老師提到,學習算法以前要計算機數學+離散數學+機率論等課程的知識,因此一直學很差算法的程序猿最好仍是從基礎入手,這都是中國式教育惹的禍啊!(此處省略一萬字......)java


原文地址:Building a Java chart server[1]git

項目源代碼:Socket_Chatgithub

文件夾

正文

計劃

咱們已經準備好從client接收網絡鏈接。如下講聊天室怎麼樣工做的。算法


上面咱們提到 Java語言提供了Socket類。它表明了程序到某處的鏈接,而且可以數據傳輸。網絡


但是首先咱們如何得到socket呢?client。從定義上看,初始化鏈接server端。因此。server端的第一件事是等待傳入的鏈接。多線程

咱們需要Sockets鏈接上咱們的client。socket


現在是引入ServerSocket的時候。一個對象工做時簡單的:監聽端口,新的鏈接傳入,建立一個Socket表明新的鏈接。學習

—————————————————————————————————————————————————————————————————————————ui

接收 Sockets

 記住你的程序可能會服務給很是多client整個互聯網。而且這些client會鏈接你的server端,而且它們互相不聯繫。也就是說。沒法控制它們的順序,或者時間,當鏈接到達時。咱們稍後會看到。多線程是一種處理鏈接傑出的方式,一旦這些鏈接都傳入的時候。


然而,咱們仍然盡力處理它們到達的鏈接。


socket提供了一種直接解決方式:serializes(序列化)傳入的鏈接。讓它們看起來是請求它們的時候。會一個一個的到達。


這是它的樣子。從大致上看:


// 開始監聽端口
ServerSocket ss = new ServerSocket( port );
// 始終循環
while (true) {
// 得到一個鏈接
Socket newSocket = ss.accept();
// 處理鏈接
// ...
}

accept() 程序是關鍵所在。當ServerSocket被調用時,它會返回一個新的Socket對象,表明一個新傳入的鏈接。

在你處理鏈接以後,會調用accept()程序取得下一個鏈接。這樣的方式下,無論你傳入的鏈接多快,無論你機器上有多少處理器或網絡接口,在某一時間你僅僅會獲得一個鏈接。

(假設此時沒有不論什麼鏈接。accept()程序會堵塞 -- 不返回不論什麼東西 -- 知道有鏈接傳入)

—————————————————————————————————————————————————————————————————————————

序列號傳入的請求



通常來講,處理同一時候發生的事情上, 序列化是一種有效的方式。

然而。一個潛在的缺陷。它不可以並行。也就是說,序列化阻止咱們節省時間在同一時間工做在多個事情上。上面的代碼中,正在處理一個鏈接的時候。其它的鏈接就會掛起。


但是序列化對於咱們不是問題。因爲每次一個鏈接傳入的時候,咱們會建立一個新的線程處理它。一旦新的線程建立。它就當即處理新的鏈接。咱們的接收循環可以繼續接收新的鏈接傳入。

假設建立新線程的行爲足夠快。鏈接就不會被掛起。

—————————————————————————————————————————————————————————————————————————

代碼


讓咱們一塊兒看看代碼。如下的代碼就是咱們上面說的:監聽接口,接受新的鏈接,建立線程處理它們。以後仍然會有其它實用的事情要作。

代碼例如如下所看到的:


private void listen( int port ) throws IOException {
// 建立ServerSocket
ss = new ServerSocket( port );
// 告訴你們我已經準備好了
System.out.println( "Listening on "+ss );
// 始終接收鏈接
while (true) {
// 抓取下一個來的鏈接
Socket s = ss.accept();
// 告訴你們咱們獲得它了
System.out.println( "Connection from "+s );
// 爲了寫出數據給其它方面,建立一個DataOutputStream
DataOutputStream dout = new DataOutputStream( s.getOutputStream() );
// 保存該流,這樣咱們就不需要又一次建立它
outputStreams.put( s, dout );
// 爲該鏈接建立一個新線程。以後忘記它
new ServerThread( this, s );
}
}


—————————————————————————————————————————————————————————————————————————

結束語

代碼清單最後一行建立一個線程處理新的鏈接。這個線程是一個叫ServerThread的對象,它是下一節的主題。

參考文獻

[1]. Building  a Java chart server

[2]. Java sockets 101以及中文系列 JAVA套接字(Socket)101

[3]. Java socket通訊基本原理介紹

相關文章
相關標籤/搜索