3-基于TCP的Socket通信_(tái)第1頁(yè)
3-基于TCP的Socket通信_(tái)第2頁(yè)
3-基于TCP的Socket通信_(tái)第3頁(yè)
3-基于TCP的Socket通信_(tái)第4頁(yè)
3-基于TCP的Socket通信_(tái)第5頁(yè)
已閱讀5頁(yè),還剩28頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、3 基于基于TCP的的Socket通信通信3.1 Socket類與類與ServerSocket類類3.2 簡(jiǎn)單服務(wù)器程序簡(jiǎn)單服務(wù)器程序3.3 簡(jiǎn)單客戶端程序簡(jiǎn)單客戶端程序3.4 基于多線程的服務(wù)器程序基于多線程的服務(wù)器程序3.5 基于多線程的客戶端程序基于多線程的客戶端程序基于基于TCP的的Socket通信通信n基于基于TCP的的Socket通信是通過指定通信是通過指定IP地址地址和和port 號(hào)號(hào),采用,采用C/S模式建立模式建立TCP協(xié)議下的兩個(gè)通信進(jìn)程協(xié)議下的兩個(gè)通信進(jìn)程間的連接,實(shí)現(xiàn)可靠的雙向通信。間的連接,實(shí)現(xiàn)可靠的雙向通信。nJava中:實(shí)現(xiàn)中:實(shí)現(xiàn)客戶端客戶端套接字的套接字的So

2、cket類;實(shí)現(xiàn)類;實(shí)現(xiàn)服服務(wù)器端務(wù)器端套接字的套接字的ServerSocket類。類。2Socket類的構(gòu)造方法與常用方法類的構(gòu)造方法與常用方法構(gòu)造方法構(gòu)造方法功能功能Socket(InetAddress address, int port)Socket(String host, int port)創(chuàng)建一個(gè)流套接字并將其連接到指定創(chuàng)建一個(gè)流套接字并將其連接到指定IP地址的指定端口號(hào)地址的指定端口號(hào)創(chuàng)建一個(gè)流套接字并將其連接到指定創(chuàng)建一個(gè)流套接字并將其連接到指定主機(jī)上的指定端口號(hào)主機(jī)上的指定端口號(hào)表表3-2 常用方法及功能常用方法及功能常用方法常用方法功能功能public void close

3、()public InetAddress getInetAddress()* public InputStream getInputStream()public InetAddress getLocalAddress()public int getLocalPort()*public OutputStream getOutputStream()public int getPort()關(guān)閉此套接字關(guān)閉此套接字返回套接字連接的地址返回套接字連接的地址返回套接字的輸入流返回套接字的輸入流獲取套接字綁定本地地址獲取套接字綁定本地地址返回套接字綁定的本地端口返回套接字綁定的本地端口返回套接字的輸出流返回

4、套接字的輸出流返回套接字連接的遠(yuǎn)程端口返回套接字連接的遠(yuǎn)程端口3ServerSocket類構(gòu)造方法與常用方法類構(gòu)造方法與常用方法構(gòu)造方法構(gòu)造方法功能功能 ServerSocket(int port)ServerSocket(int port, int backlog)ServerSocket(int port, int backlog,InetAddress bindAddr)創(chuàng)建綁定到特定端口服務(wù)器套接字創(chuàng)建綁定到特定端口服務(wù)器套接字用用backlog創(chuàng)建服務(wù)器套接字創(chuàng)建服務(wù)器套接字,將其綁將其綁定到指定本地端口號(hào)定到指定本地端口號(hào)用指定端口、偵聽用指定端口、偵聽backlog和要綁定和要綁

5、定本地本地IP地址創(chuàng)建服務(wù)器地址創(chuàng)建服務(wù)器常用方法常用方法功能功能* public Socket accept()public void close()public InetAddress getInetAddress()public int getLocalPort()偵聽并接受到此套接字的連接偵聽并接受到此套接字的連接關(guān)閉此套接字關(guān)閉此套接字返回此服務(wù)器套接字的本地地址返回此服務(wù)器套接字的本地地址返回此套接字在其上偵聽的端口返回此套接字在其上偵聽的端口3.1 Socket類與類與ServerSocket類類nSocket通信原理通信原理網(wǎng)絡(luò)中基于網(wǎng)絡(luò)中基于Socket通信的兩個(gè)進(jìn)程間建立連

6、接通信的兩個(gè)進(jìn)程間建立連接時(shí),會(huì)將其中一個(gè)進(jìn)程作為客戶端,而另一個(gè)進(jìn)時(shí),會(huì)將其中一個(gè)進(jìn)程作為客戶端,而另一個(gè)進(jìn)程作為服務(wù)器端。程作為服務(wù)器端。n(1)C/S模型模型qServerSocket類和類和Socket類實(shí)現(xiàn)通信的類實(shí)現(xiàn)通信的C/S模型。模型。(1)基于)基于Socket通信的通信的C/S模型模型(續(xù)一續(xù)一)圖圖3-1 使用使用ServerSocket類和類和Socket類實(shí)現(xiàn)通信的類實(shí)現(xiàn)通信的C/S模型模型 n基于基于Socket通信的基本算法通信的基本算法:S1:用用一致端口一致端口分別建分別建Socket類和類和ServerSocket類對(duì)象類對(duì)象;S2:服務(wù)器端服務(wù)器端Serv

7、erSocket類對(duì)象用類對(duì)象用accept()監(jiān)視端口;監(jiān)視端口;S3:打開連接到客戶端打開連接到客戶端Socket類對(duì)象的輸入類對(duì)象的輸入/輸出流,向輸出流,向服務(wù)器端服務(wù)器端ServerSocket類對(duì)象發(fā)送相應(yīng)請(qǐng)求,服務(wù)器類對(duì)象發(fā)送相應(yīng)請(qǐng)求,服務(wù)器接受客戶請(qǐng)求并返回客戶端接受客戶請(qǐng)求并返回客戶端Socket類對(duì)象,從而建立類對(duì)象,從而建立連接;連接;S4:通信雙方按照一定協(xié)議對(duì)通信雙方按照一定協(xié)議對(duì)Socket對(duì)象進(jìn)行讀對(duì)象進(jìn)行讀/寫操作寫操作;S5:關(guān)閉關(guān)閉Socket。(2)客戶端進(jìn)程)客戶端進(jìn)程n按給定按給定服務(wù)器端地址服務(wù)器端地址及及端口號(hào)端口號(hào),建立客戶端套接,建立客戶端套接

8、字字Socket類對(duì)象,并向服務(wù)器端發(fā)送請(qǐng)求,等待類對(duì)象,并向服務(wù)器端發(fā)送請(qǐng)求,等待服務(wù)器響應(yīng)。代碼如下:服務(wù)器響應(yīng)。代碼如下:try / 創(chuàng)建客戶端創(chuàng)建客戶端Socket類的對(duì)象類的對(duì)象socket,服務(wù)器地址取本地,端口號(hào)為服務(wù)器地址取本地,端口號(hào)為8888 Socket socket = new Socket(localhost, 8888); catch (UnknownHostException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();(3)服務(wù)器端進(jìn)程)服務(wù)器端進(jìn)程n按與客戶端商定的端口號(hào)建

9、立服務(wù)器端套接字按與客戶端商定的端口號(hào)建立服務(wù)器端套接字ServerSocket類對(duì)象,然后用類對(duì)象,然后用ServerSocket對(duì)象對(duì)象方法方法accept()監(jiān)聽該端口是否有客戶端發(fā)送請(qǐng)求。監(jiān)聽該端口是否有客戶端發(fā)送請(qǐng)求。q若無請(qǐng)求,則服務(wù)器進(jìn)程處于等待狀態(tài)并一直監(jiān)聽若無請(qǐng)求,則服務(wù)器進(jìn)程處于等待狀態(tài)并一直監(jiān)聽端口;一旦接收到客戶端請(qǐng)求,端口;一旦接收到客戶端請(qǐng)求,accept()獲取返回獲取返回該客戶端對(duì)象該客戶端對(duì)象,即在服務(wù)器端保存與客戶端的連接,即在服務(wù)器端保存與客戶端的連接,接下來可利用該連接實(shí)現(xiàn)與客戶端之間的數(shù)據(jù)交換。接下來可利用該連接實(shí)現(xiàn)與客戶端之間的數(shù)據(jù)交換。(3)服務(wù)器

10、端進(jìn)程)服務(wù)器端進(jìn)程n建立服務(wù)器端套接字及端口監(jiān)聽的代碼:建立服務(wù)器端套接字及端口監(jiān)聽的代碼:try ServerSocket serversocket = new ServerSocket(8888);Socket socket = serversocket.accept(); catch (IOException e) e.printStackTrace();n強(qiáng)調(diào):服務(wù)器的端口號(hào)和客戶端進(jìn)程中指定端強(qiáng)調(diào):服務(wù)器的端口號(hào)和客戶端進(jìn)程中指定端口號(hào)應(yīng)該一致,否則不能建立連接??谔?hào)應(yīng)該一致,否則不能建立連接。 3.2 簡(jiǎn)單服務(wù)器程序簡(jiǎn)單服務(wù)器程序n由服務(wù)器端程序與客戶端程序兩部分組成,基本功能是

11、:由服務(wù)器端程序與客戶端程序兩部分組成,基本功能是:n()服務(wù)器端程序()服務(wù)器端程序q監(jiān)聽監(jiān)聽C/S雙方約定的端口(雙方約定的端口(55558),等待并接收客戶請(qǐng)求,),等待并接收客戶請(qǐng)求,接受客戶請(qǐng)求后建立一個(gè)至客戶端的基于套接字的連接,然接受客戶請(qǐng)求后建立一個(gè)至客戶端的基于套接字的連接,然后利用該連接返回到客戶端的后利用該連接返回到客戶端的Socket對(duì)象,創(chuàng)建一個(gè)服務(wù)對(duì)象,創(chuàng)建一個(gè)服務(wù)器端輸入流器端輸入流InputStream和一個(gè)服務(wù)器端輸出流和一個(gè)服務(wù)器端輸出流OutputStream,同時(shí)將它們分別包裝成便于操作與刷新的,同時(shí)將它們分別包裝成便于操作與刷新的BufferedRea

12、der輸入流和輸入流和PrintWriter輸出流。輸出流。q然后,服務(wù)器端從然后,服務(wù)器端從InputStream讀入客戶端輸出的數(shù)據(jù),用讀入客戶端輸出的數(shù)據(jù),用OutputStream向客戶端輸出數(shù)據(jù),直到接收到客戶端的數(shù)向客戶端輸出數(shù)據(jù),直到接收到客戶端的數(shù)據(jù)終止標(biāo)志據(jù)終止標(biāo)志“結(jié)束結(jié)束”為止,為止,q最后關(guān)閉連接,釋放網(wǎng)絡(luò)資源,結(jié)束本次通信。最后關(guān)閉連接,釋放網(wǎng)絡(luò)資源,結(jié)束本次通信。()客戶端程序()客戶端程序n首先創(chuàng)建客戶端首先創(chuàng)建客戶端Socket對(duì)象后,然后在約定端口對(duì)象后,然后在約定端口向服務(wù)器端發(fā)送請(qǐng)求,待服務(wù)器端接受請(qǐng)求后建向服務(wù)器端發(fā)送請(qǐng)求,待服務(wù)器端接受請(qǐng)求后建立基于套

13、接字的連接,然后利用該連接的立基于套接字的連接,然后利用該連接的Socket對(duì)象,創(chuàng)建一個(gè)客戶端輸入流對(duì)象,創(chuàng)建一個(gè)客戶端輸入流InputStream和一和一個(gè)客戶端輸出流個(gè)客戶端輸出流OutputStream,同時(shí)將它們分別,同時(shí)將它們分別包裝成便于操作與刷新的包裝成便于操作與刷新的BufferedReader輸入流輸入流和和PrintWriter輸出流。輸出流。n然后,客戶端從然后,客戶端從InputStream讀入服務(wù)器端輸出讀入服務(wù)器端輸出的數(shù)據(jù),用的數(shù)據(jù),用OutputStream向服務(wù)器端輸出數(shù)據(jù),向服務(wù)器端輸出數(shù)據(jù),直到發(fā)送完數(shù)據(jù)終止標(biāo)志直到發(fā)送完數(shù)據(jù)終止標(biāo)志“結(jié)束結(jié)束”為止,最

14、后關(guān)為止,最后關(guān)閉連接,釋放網(wǎng)絡(luò)資源,結(jié)束本次通信。閉連接,釋放網(wǎng)絡(luò)資源,結(jié)束本次通信。n例例3-1 基于基于Socket的簡(jiǎn)單服務(wù)器程序。的簡(jiǎn)單服務(wù)器程序。q程序清單程序清單: DaytimeClient.java【例【例3-1】程序分析:程序分析:n服務(wù)器端程序與客戶端程序都使用同樣的服務(wù)器端程序與客戶端程序都使用同樣的端口端口號(hào)號(hào)(55558), 服務(wù)器端程序在本地機(jī)器上運(yùn)行服務(wù)器端程序在本地機(jī)器上運(yùn)行其其ServerSocket只需要一個(gè)端口號(hào),而不需要只需要一個(gè)端口號(hào),而不需要IP地址。地址。n服務(wù)器端服務(wù)器端ServerSocket類的實(shí)例調(diào)用類的實(shí)例調(diào)用accept()方法時(shí),會(huì)

15、陷入阻塞狀態(tài),直到某個(gè)客戶端程序方法時(shí),會(huì)陷入阻塞狀態(tài),直到某個(gè)客戶端程序請(qǐng)求與它建立連接。請(qǐng)求與它建立連接。q連接正常建立后,連接正常建立后,accept()將返回一個(gè)客戶端將返回一個(gè)客戶端Socket類的實(shí)例,即本次類的實(shí)例,即本次C/S套接字連接的實(shí)套接字連接的實(shí)例,它是一個(gè)可讀寫的雙向管道。例,它是一個(gè)可讀寫的雙向管道?!纠纠?-1】程序分析:程序分析: (續(xù)一續(xù)一)n必須將必須將ServerSocket構(gòu)造方法、構(gòu)造方法、accept()方法和方法和I/O流操作方法等放在一個(gè)流操作方法等放在一個(gè)try-finally代碼塊,以確保代碼塊,以確保無論什么方式結(jié)束,無論什么方式結(jié)束,S

16、erverSocket、Socket和和I/O流流都能被正確關(guān)閉。都能被正確關(guān)閉。q若若ServerSocket對(duì)象創(chuàng)建失敗,則拋出對(duì)象創(chuàng)建失敗,則拋出IOException異常,并由異常,并由finally塊確保無論正常與塊確保無論正常與否結(jié)束通信,均會(huì)關(guān)閉連接、釋放網(wǎng)絡(luò)套接字等資否結(jié)束通信,均會(huì)關(guān)閉連接、釋放網(wǎng)絡(luò)套接字等資源。由于套接字使用了重要的非內(nèi)存資源,因此要源。由于套接字使用了重要的非內(nèi)存資源,因此要特別謹(jǐn)慎,必須以顯式方式將它們及時(shí)清除。特別謹(jǐn)慎,必須以顯式方式將它們及時(shí)清除。【例【例11-5】程序分析:程序分析: (續(xù)二續(xù)二)n當(dāng)程序中利用標(biāo)準(zhǔn)輸出流當(dāng)程序中利用標(biāo)準(zhǔn)輸出流Sys

17、tem.out將將ServerSocket類構(gòu)造的實(shí)例和類構(gòu)造的實(shí)例和accept()方法返回的方法返回的Socket類的實(shí)例打印輸出時(shí),自動(dòng)調(diào)用了它們的類的實(shí)例打印輸出時(shí),自動(dòng)調(diào)用了它們的toString()方法,其結(jié)果如下:方法,其結(jié)果如下:ServerSocket addr=0.0.0.0/0.0.0.0,port=0,localport=55558Socket addr =/127.0.0.1,port=3024,localport=55558【例【例11-5】程序分析:程序分析: (續(xù)三續(xù)三)n數(shù)據(jù)交換部分?jǐn)?shù)據(jù)交換部分:服務(wù)器端的輸入流:服務(wù)器端的輸入流InputStream和輸出和

18、輸出流流OutputStream是從是從Socket類的實(shí)例創(chuàng)建的。類的實(shí)例創(chuàng)建的。q它采用它采用裝飾模式裝飾模式,先利用兩個(gè),先利用兩個(gè)“轉(zhuǎn)換器轉(zhuǎn)換器”類類InputStreamReader和和OutputStreamWriter,將,將InputStream和和OutputStream對(duì)象分別轉(zhuǎn)換成為對(duì)象分別轉(zhuǎn)換成為Reader和和Writer對(duì)象。對(duì)象。q再利用類再利用類BufferedReader和和PrintWriter,將,將Reader和和Writer對(duì)象分別轉(zhuǎn)換成為對(duì)象分別轉(zhuǎn)換成為BufferedReader和和PrintWriter對(duì)象,以方便讀寫與刷新操作。對(duì)象,以方便讀寫

19、與刷新操作。q若構(gòu)造方法若構(gòu)造方法PrintWriter(Writer out, boolean autoFlush)中的中的“autoFlush”為為“true”時(shí),則時(shí),則PrintWriter類的類的out對(duì)象每次調(diào)用對(duì)象每次調(diào)用println()結(jié)束時(shí)會(huì)自結(jié)束時(shí)會(huì)自動(dòng)刷新輸出緩沖區(qū)(但不適用于動(dòng)刷新輸出緩沖區(qū)(但不適用于print()語(yǔ)句),使輸出語(yǔ)句),使輸出流中的信息能即時(shí)通過網(wǎng)絡(luò)傳遞出去。流中的信息能即時(shí)通過網(wǎng)絡(luò)傳遞出去。11.3.3 簡(jiǎn)單客戶端程序簡(jiǎn)單客戶端程序n根據(jù)根據(jù)11.3.2節(jié)中基于節(jié)中基于Socket的通信系統(tǒng)中對(duì)客戶端程序功的通信系統(tǒng)中對(duì)客戶端程序功能的分析,其實(shí)現(xiàn)

20、代碼如例能的分析,其實(shí)現(xiàn)代碼如例11-6所示。所示。nP400【例【例11-6】 基于基于Socket的簡(jiǎn)單客戶端程序。的簡(jiǎn)單客戶端程序。q程序清單程序清單11-6: SimpletClientSocketDemo.javaq運(yùn)行方法:在待運(yùn)行類的主目錄下編寫并運(yùn)行運(yùn)行方法:在待運(yùn)行類的主目錄下編寫并運(yùn)行SimpletClientSocketDemo.bat文件,其內(nèi)容如下:文件,其內(nèi)容如下:java socket.SimpletClientSocketDemopauseq運(yùn)行結(jié)果:如圖運(yùn)行結(jié)果:如圖11-4所示。所示。圖圖11-4 例例11-6中客戶端的輸出結(jié)果中客戶端的輸出結(jié)果 【例【例1

21、1-6】程序分析:程序分析:n客戶端使用本地主機(jī)(客戶端使用本地主機(jī)(Localhost)地址與位于同一臺(tái))地址與位于同一臺(tái)機(jī)器中的服務(wù)器程序建立連接,因此可在一臺(tái)物理機(jī)器中機(jī)器中的服務(wù)器程序建立連接,因此可在一臺(tái)物理機(jī)器中完成測(cè)試,若將客戶端程序與服務(wù)器端程序分布在一個(gè)物完成測(cè)試,若將客戶端程序與服務(wù)器端程序分布在一個(gè)物理網(wǎng)絡(luò)中,則可在客戶端理網(wǎng)絡(luò)中,則可在客戶端Socket對(duì)象中指定服務(wù)器的對(duì)象中指定服務(wù)器的IP地址,即可實(shí)現(xiàn)通信。地址,即可實(shí)現(xiàn)通信。n客戶端程序中獲得本地主機(jī)客戶端程序中獲得本地主機(jī)IP地址的地址的InetAddress的途的途徑有三種:使用徑有三種:使用null、使用、

22、使用localhost,或者直接使用保,或者直接使用保留地址留地址127.0.0.1。若向。若向getByName( )傳遞一個(gè)傳遞一個(gè)null,則,則默認(rèn)尋找默認(rèn)尋找localhost,并生成特殊的保留地址,并生成特殊的保留地址127.0.0.1。注意:在創(chuàng)建名為注意:在創(chuàng)建名為socket的套接字時(shí),同時(shí)使用了的套接字時(shí),同時(shí)使用了InetAddress以及端口號(hào)。以及端口號(hào)。【例【例11-6】程序分析:程序分析: (續(xù)一續(xù)一)n服務(wù)器程序啟動(dòng)后在本地主機(jī)(服務(wù)器程序啟動(dòng)后在本地主機(jī)(127.0.0.1)上為其分配端口)上為其分配端口55558。一旦客戶端程序發(fā)出請(qǐng)求,當(dāng)前機(jī)器中的下一個(gè)可

23、用。一旦客戶端程序發(fā)出請(qǐng)求,當(dāng)前機(jī)器中的下一個(gè)可用端口就會(huì)分配給客戶端程序(此處為端口就會(huì)分配給客戶端程序(此處為3024),并同時(shí)告知與其),并同時(shí)告知與其連接的服務(wù)程序。此例中,服務(wù)器端進(jìn)程獲取的客戶端套接字連接的服務(wù)程序。此例中,服務(wù)器端進(jìn)程獲取的客戶端套接字如下所示:如下所示:Socket addr = 127.0.0.1,port=3024,localport =55558q它表示服務(wù)器進(jìn)程已接受來自它表示服務(wù)器進(jìn)程已接受來自IP為為127.0.0.1機(jī)器的機(jī)器的3024端端口的客戶端進(jìn)程的連接,同時(shí)監(jiān)聽其本地的口的客戶端進(jìn)程的連接,同時(shí)監(jiān)聽其本地的55558端口,而端口,而在客戶端

24、輸出的套接字如下所示:在客戶端輸出的套接字如下所示:Socket addr = localhost/127.0.0.1,port=55558,localport=3024q它表示客戶端進(jìn)程已用其本地端口它表示客戶端進(jìn)程已用其本地端口3024與與127.0.0.1機(jī)器上機(jī)器上的的55558端口建立了連接。端口建立了連接。 【例【例11-6】程序分析:程序分析: (續(xù)二續(xù)二)n數(shù)據(jù)交換:數(shù)據(jù)交換:創(chuàng)建好客戶端創(chuàng)建好客戶端Socket對(duì)象后,調(diào)用其對(duì)象后,調(diào)用其getInputStream()和和getOutputStream()方法分別創(chuàng)建客戶端方法分別創(chuàng)建客戶端的輸入流的輸入流InputStre

25、am和輸出流和輸出流OutputStream,并與服務(wù)器,并與服務(wù)器端程序一樣采用裝飾模式,最終將它們分別轉(zhuǎn)換成為端程序一樣采用裝飾模式,最終將它們分別轉(zhuǎn)換成為BufferedReader輸入流和輸入流和PrintWriter輸出流,以方便讀寫與輸出流,以方便讀寫與刷新操作。刷新操作。q為了測(cè)試通信正常與否,此處,客戶端輸出流通過發(fā)送為了測(cè)試通信正常與否,此處,客戶端輸出流通過發(fā)送“From Client ”加數(shù)字的字符串?dāng)?shù)據(jù)來初始化通信,而客加數(shù)字的字符串?dāng)?shù)據(jù)來初始化通信,而客戶端輸入流則從服務(wù)器輸出流中接收戶端輸入流則從服務(wù)器輸出流中接收“From Server ”加數(shù)加數(shù)字的字符串行,寫

26、入字的字符串行,寫入System.out后,在屏幕打印輸出。最后,在屏幕打印輸出。最后,為終止數(shù)據(jù)交換,客戶端輸出流通過向服務(wù)器端輸入流后,為終止數(shù)據(jù)交換,客戶端輸出流通過向服務(wù)器端輸入流發(fā)送發(fā)送“結(jié)束結(jié)束”字符串,以結(jié)束本次通信,釋放套接字連接資字符串,以結(jié)束本次通信,釋放套接字連接資源。源?!纠纠?1-6】程序分析:程序分析: (續(xù)三續(xù)三)n在客戶端程序中同樣采用在客戶端程序中同樣采用try-finally塊,以確保塊,以確保由由Socket代表的網(wǎng)絡(luò)資源能得到正確的清除。代表的網(wǎng)絡(luò)資源能得到正確的清除。q套接字建立的套接字建立的“專用專用”連接會(huì)一直持續(xù)到明確連接會(huì)一直持續(xù)到明確斷開連

27、接為止(除非某端或中間鏈路出現(xiàn)故障斷開連接為止(除非某端或中間鏈路出現(xiàn)故障而崩潰)。在連接未拆除前,參與連接的雙方而崩潰)。在連接未拆除前,參與連接的雙方都被鎖定在通信中,且無論是否有數(shù)據(jù)傳遞,都被鎖定在通信中,且無論是否有數(shù)據(jù)傳遞,連接都會(huì)連續(xù)處于開放狀態(tài)。因此,每次通信連接都會(huì)連續(xù)處于開放狀態(tài)。因此,每次通信結(jié)束時(shí),若不及時(shí)拆除連接將會(huì)增加網(wǎng)絡(luò)的額結(jié)束時(shí),若不及時(shí)拆除連接將會(huì)增加網(wǎng)絡(luò)的額外開銷,甚至使資源耗盡,導(dǎo)致系統(tǒng)崩潰。外開銷,甚至使資源耗盡,導(dǎo)致系統(tǒng)崩潰。 11.3.4 基于多線程的服務(wù)器程序基于多線程的服務(wù)器程序n例例11-5中的中的SimpleServerSocketDemo盡管

28、能正盡管能正常工作,但每次只能為一個(gè)客戶端程序提供服務(wù)。常工作,但每次只能為一個(gè)客戶端程序提供服務(wù)。實(shí)際應(yīng)用中,要求服務(wù)器能同時(shí)處理多個(gè)客戶端實(shí)際應(yīng)用中,要求服務(wù)器能同時(shí)處理多個(gè)客戶端的請(qǐng)求。的請(qǐng)求。n解決此問題的關(guān)鍵就是將多線程處理機(jī)制應(yīng)用到解決此問題的關(guān)鍵就是將多線程處理機(jī)制應(yīng)用到網(wǎng)絡(luò)通信中來。如圖網(wǎng)絡(luò)通信中來。如圖11-5所示是在圖所示是在圖11-2的基礎(chǔ)的基礎(chǔ)上改進(jìn)而來的基于上改進(jìn)而來的基于Socket的多線程的多線程C/S通信模型,通信模型,它可應(yīng)用于對(duì)例它可應(yīng)用于對(duì)例11-5與例與例11-6的改造,從而實(shí)現(xiàn)的改造,從而實(shí)現(xiàn)響應(yīng)多客戶請(qǐng)求的數(shù)據(jù)通信,提高服務(wù)器的并發(fā)響應(yīng)多客戶請(qǐng)求的數(shù)

29、據(jù)通信,提高服務(wù)器的并發(fā)性能。性能。11.3.4 基于多線程的服務(wù)器程序基于多線程的服務(wù)器程序(續(xù)一續(xù)一)圖圖11-5 基于基于Socket的多線程的多線程C/S通信模型通信模型 n其基本思想是其基本思想是:在服務(wù)器程序中創(chuàng)建單個(gè):在服務(wù)器程序中創(chuàng)建單個(gè)ServerSocket的實(shí)例,的實(shí)例,并循環(huán)調(diào)用其并循環(huán)調(diào)用其accept( )方法以等候一個(gè)新連接。一旦方法以等候一個(gè)新連接。一旦accept( )返返回一個(gè)客戶端線程的回一個(gè)客戶端線程的Socket的實(shí)例,就用該的實(shí)例,就用該Socket實(shí)例新建一實(shí)例新建一個(gè)服務(wù)線程,為該特定的客戶端線程服務(wù)??蛻舳顺绦虿捎枚嗑€個(gè)服務(wù)線程,為該特定的客戶

30、端線程服務(wù)。客戶端程序采用多線程技術(shù)能創(chuàng)建多個(gè)程技術(shù)能創(chuàng)建多個(gè)Socket實(shí)例的線程,并能控制其活動(dòng)線程的總實(shí)例的線程,并能控制其活動(dòng)線程的總數(shù)量,以防止服務(wù)器過載和網(wǎng)絡(luò)擁塞。數(shù)量,以防止服務(wù)器過載和網(wǎng)絡(luò)擁塞。11.3.4 基于多線程的服務(wù)器程序基于多線程的服務(wù)器程序(續(xù)二續(xù)二)n例例11-7是基于多線程的服務(wù)器程序,它是對(duì)例是基于多線程的服務(wù)器程序,它是對(duì)例11-5的改進(jìn),的改進(jìn),它與它與SimpleServer SocketDemo.java很相似,只是為一很相似,只是為一個(gè)特定的客戶端線程提供服務(wù)的所有操作都被移入一個(gè)獨(dú)個(gè)特定的客戶端線程提供服務(wù)的所有操作都被移入一個(gè)獨(dú)立的線程類立的線程

31、類MultithreadServerSocket中。中。nP402【例【例11-7】 基于多線程的服務(wù)器程序?;诙嗑€程的服務(wù)器程序。q程序清單程序清單11-7: MultithreadServerSocketDemo.java11.3.4 基于多線程的服務(wù)器程序基于多線程的服務(wù)器程序(續(xù)三續(xù)三)n運(yùn)行方法:在待運(yùn)行類的主目錄下編寫并運(yùn)行運(yùn)行方法:在待運(yùn)行類的主目錄下編寫并運(yùn)行MultithreadServerSocketDemo.bat文件,其內(nèi)容如下:文件,其內(nèi)容如下:java socket.MultithreadServerSocketDemopause圖圖11-6 例例11-7中服中服

32、務(wù)器務(wù)器端輸端輸出的出的部分部分結(jié)果結(jié)果 【例【例11-7】程序分析:程序分析:n一旦有新的客戶端一旦有新的客戶端Socket線程請(qǐng)求建立一個(gè)連線程請(qǐng)求建立一個(gè)連接時(shí),服務(wù)器端的接時(shí),服務(wù)器端的MultithreadServerSocket線程線程會(huì)取得由會(huì)取得由accept( )返回的返回的Socket對(duì)象。然后與例對(duì)象。然后與例11-5一樣,創(chuàng)建一個(gè)一樣,創(chuàng)建一個(gè)BufferedReader輸入流和一輸入流和一個(gè)個(gè)PrintWriter輸出流。最后,它調(diào)用輸出流。最后,它調(diào)用Thread的的start( )方法進(jìn)行服務(wù)線程的初始化,然后調(diào)用方法進(jìn)行服務(wù)線程的初始化,然后調(diào)用run( )完成

33、數(shù)據(jù)交換。數(shù)據(jù)交換操作與例完成數(shù)據(jù)交換。數(shù)據(jù)交換操作與例11-5相同。相同?!纠纠?1-7】程序分析:程序分析: (續(xù)一續(xù)一)n套接字的清除必須進(jìn)行謹(jǐn)慎的設(shè)計(jì)。此例中,套接字的清除必須進(jìn)行謹(jǐn)慎的設(shè)計(jì)。此例中,ServerSocket套接字是在套接字是在MultithreadServerSocket外部創(chuàng)建的,所以清除外部創(chuàng)建的,所以清除工作可以工作可以“共享共享”。若。若MultithreadServerSocket構(gòu)造方法失敗,則只需向調(diào)用者拋出一個(gè)異常即構(gòu)造方法失敗,則只需向調(diào)用者拋出一個(gè)異常即可,然后由調(diào)用者負(fù)責(zé)線程的清除。但若構(gòu)造方可,然后由調(diào)用者負(fù)責(zé)線程的清除。但若構(gòu)造方法成功,則

34、必須由法成功,則必須由MultithreadServerSocket對(duì)象對(duì)象負(fù)責(zé)線程的清除,這是在它的負(fù)責(zé)線程的清除,這是在它的run( )里進(jìn)行的。里進(jìn)行的。11.3.5 基于多線程的客戶端程序基于多線程的客戶端程序n為了驗(yàn)證服務(wù)器代碼確實(shí)能為多個(gè)客戶端提供服務(wù),下面為了驗(yàn)證服務(wù)器代碼確實(shí)能為多個(gè)客戶端提供服務(wù),下面這個(gè)程序?qū)⑹褂镁€程創(chuàng)建許多客戶端,并與相同的服務(wù)器這個(gè)程序?qū)⑹褂镁€程創(chuàng)建許多客戶端,并與相同的服務(wù)器建立連接。每個(gè)線程的建立連接。每個(gè)線程的“存在時(shí)間存在時(shí)間”都是有限的。一旦到都是有限的。一旦到期,就留出空間以便創(chuàng)建一個(gè)新線程。允許創(chuàng)建的線程的期,就留出空間以便創(chuàng)建一個(gè)新線程。允許創(chuàng)建的線程的最大數(shù)量是由最大數(shù)量是由final int MAXTHREADS決定的。這個(gè)值很決

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論