




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
網(wǎng)絡(luò)編程基礎(chǔ)網(wǎng)絡(luò)編程基礎(chǔ)網(wǎng)絡(luò)聊天室范例演示需要解決的問(wèn)題1)如何與對(duì)方機(jī)器進(jìn)行連接2)如何找到對(duì)應(yīng)的應(yīng)用程序3)對(duì)收到的信息怎樣實(shí)現(xiàn)是廣播還是一對(duì)一?網(wǎng)絡(luò)聊天室范例演示網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2Internet上互相通信的計(jì)算機(jī)采用的協(xié)議是TCP協(xié)議或者UDP協(xié)議,它們的結(jié)構(gòu)類(lèi)似于:網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2Internet上互相通信的網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2TCP是傳輸控制協(xié)議,也稱為“基于數(shù)據(jù)流的套接字”,根據(jù)該協(xié)議的設(shè)計(jì)宗旨,它具有高度的可靠性,而且能保證數(shù)據(jù)順利到達(dá)目的地。換言之,它允許重傳那些由于各種原因半路“走失”的數(shù)據(jù)。而且收到字節(jié)的順序與它們發(fā)出的順序是一樣的。TCP的高可靠性需要付出的代價(jià)是:高開(kāi)銷(xiāo)(需要有很多的信息用于控制信息)。而UDP稱為用戶數(shù)據(jù)報(bào)協(xié)議,它并不刻意追求數(shù)據(jù)報(bào)會(huì)完全發(fā)送出去,也不能擔(dān)保抵達(dá)的順序與它們發(fā)出時(shí)一樣。因此,UDP被認(rèn)為是一種不可靠協(xié)議。但是,它的速度快,對(duì)于某些應(yīng)用來(lái)說(shuō)(例如聲音),如果速度并質(zhì)量更重要,就可以采用UDP協(xié)議。大多數(shù)互聯(lián)網(wǎng)游戲也是采用UDP協(xié)議。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2TCP是傳輸控制協(xié)議,也稱為網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2機(jī)器標(biāo)識(shí)為了分辨出網(wǎng)絡(luò)上的每一臺(tái)機(jī)器,必須有一種機(jī)制能獨(dú)一無(wú)二地標(biāo)識(shí)出網(wǎng)絡(luò)內(nèi)的每臺(tái)機(jī)器。這可以通過(guò)IP地址來(lái)實(shí)現(xiàn)。IP地址以兩種形式存在:直接IP地址(如)域名()。
網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2機(jī)器標(biāo)識(shí)網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2服務(wù)器和客戶機(jī)網(wǎng)絡(luò)最基本的精神是讓兩臺(tái)計(jì)算機(jī)連接在一起,并相互“溝通”。一旦兩臺(tái)計(jì)算機(jī)發(fā)現(xiàn)了對(duì)方,就可以開(kāi)始溝通,但它們?cè)鯓硬拍堋鞍l(fā)現(xiàn)”對(duì)方呢??jī)膳_(tái)計(jì)算機(jī)要發(fā)現(xiàn)對(duì)方,通常需要其中一臺(tái)扮演“服務(wù)器”的角色,另一臺(tái)扮演“客戶機(jī)”的角色。客戶機(jī)用來(lái)發(fā)出連接請(qǐng)求,而服務(wù)器用來(lái)等待連接請(qǐng)求。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2服務(wù)器和客戶機(jī)網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2客戶機(jī)發(fā)出連接請(qǐng)求到服務(wù)器(通過(guò)IP地址),請(qǐng)求信息在網(wǎng)絡(luò)上傳輸,當(dāng)服務(wù)器在接到連接請(qǐng)求并確認(rèn)后,建立與客戶機(jī)的連接。一旦連接建立好,服務(wù)器和客戶機(jī)之間就變成了一種雙向通信,那么無(wú)論是對(duì)服務(wù)器端還是對(duì)客戶機(jī)端來(lái)說(shuō),連接就變成了一個(gè)IO數(shù)據(jù)流對(duì)象。從這是開(kāi)始,我們就可以象讀寫(xiě)一個(gè)普通的文件一樣來(lái)對(duì)待連接。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2客戶機(jī)發(fā)出連接請(qǐng)求到服務(wù)器(網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2端口有些時(shí)候,一個(gè)IP地址并不足以完整標(biāo)識(shí)一個(gè)服務(wù)器。這是由于在一臺(tái)計(jì)算機(jī)中,往往運(yùn)行著多個(gè)服務(wù)器(即不同的網(wǎng)絡(luò)應(yīng)用程序)。為了標(biāo)識(shí)是哪個(gè)服務(wù)器,就需要用到一個(gè)端口。例如,通常來(lái)說(shuō)HTTP采用的是80端口,F(xiàn)TP采用的是21端口。端口并不是機(jī)器上一個(gè)物理上存在的場(chǎng)所,而是一種軟件抽象(主要是為了表達(dá)的方便)??蛻舫绦蛑廊绾瓮ㄟ^(guò)機(jī)器的IP地址同服務(wù)器連接,但怎樣才能同自己真正需要的那種服務(wù)連接呢(一般每個(gè)端口都運(yùn)行著一種服務(wù),一臺(tái)機(jī)器可能提供了多種服務(wù),例如HTTP、FTP)?端口在這里扮演了重要的角色,它是必需的一種二級(jí)定址措施。也就是說(shuō),我們請(qǐng)求一個(gè)特定的端口,就是請(qǐng)求與那個(gè)端口編號(hào)關(guān)聯(lián)的服務(wù)。系統(tǒng)保留了使用端口1到端口1024的權(quán)利,所以,在我們?cè)O(shè)計(jì)網(wǎng)絡(luò)通信程序時(shí),一般不應(yīng)站用這些端口。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2端口網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2套接字
Socket套接字也是一種軟件形式的抽象。用于表達(dá)兩臺(tái)機(jī)器間一個(gè)連接的“通道”。針對(duì)一個(gè)特定的連接,每臺(tái)機(jī)器上都有一個(gè)“套接字”,通過(guò)“套接字”,兩臺(tái)機(jī)器之間就形成了一條“虛擬”的通道。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2套接字Java的網(wǎng)絡(luò)編程類(lèi)JDK提供了1個(gè)包,在該包中,主要包含如下的幾個(gè)類(lèi):1.Java中IP地址的表示(InetAddress類(lèi))
包中提供了一個(gè)InetAddress類(lèi),該類(lèi)用于表示一個(gè)IP地址。它常用的方法有:(1)publicstaticInetAddressgetByName(String
host)返回字符串host所表示的IP地址。(2)publicstaticInetAddressgetLocalHost()返回本機(jī)IP地址(如果你的機(jī)器設(shè)置了IP地址,則返回你自己的IP,否則返回默認(rèn)的IP地址:)。Java的網(wǎng)絡(luò)編程類(lèi)JDK提供了1個(gè)包,在該Java的網(wǎng)絡(luò)編程類(lèi)2.服務(wù)器端口打開(kāi)(ServerSocket類(lèi))ServerSocket類(lèi)用于在服務(wù)器端打開(kāi)某一個(gè)端口,等待客戶端的連接請(qǐng)求,它常用的方法有:(1)構(gòu)造器方法publicServerSocket(int
port)用于打開(kāi)服務(wù)器port端口。(2)publicSocketaccept()用于等待客戶連接,當(dāng)連接成功時(shí),形成一個(gè)套接字對(duì)象。(3)publicvoidclose()關(guān)閉用戶連接。Java的網(wǎng)絡(luò)編程類(lèi)2.服務(wù)器端口打開(kāi)(ServerSockJava的網(wǎng)絡(luò)編程類(lèi)3.套接字建立(Socket類(lèi))
Socket類(lèi)用于套接字的建立。它常用的方法有:(1)構(gòu)造器方法publicSocket(InetAddress
address,int
port)用于客戶端與指定的服務(wù)器IP地址及服務(wù)器端口進(jìn)行套接字連接。(2)publicvoidclose()關(guān)閉用戶連接。(3)publicInputStreamgetInputStream()從套接字返回一個(gè)輸入流(4)publicOutputStreamgetOutputStream()從套接字返回一個(gè)輸出流Java的網(wǎng)絡(luò)編程類(lèi)3.套接字建立(Socket類(lèi))服務(wù)器的連接過(guò)程
服務(wù)器的工作就是偵聽(tīng)來(lái)自客戶機(jī)的連接請(qǐng)求并建立連接。因此,對(duì)于服務(wù)器端來(lái)說(shuō),網(wǎng)絡(luò)編程的步驟是:(1)創(chuàng)建ServerSocket對(duì)象:ServerSocketserver=newServerSocket(PORT),其中,PORT是指服務(wù)器打開(kāi)哪個(gè)端口來(lái)等待和建立連接。(2)等待連接:Socketsocket=server.accept(),連接形成是以套接字來(lái)表示的,一旦連接成功,就會(huì)在服務(wù)器—客戶機(jī)之間形成一個(gè)套接字。(3)一旦連接建立好(即服務(wù)器—客戶機(jī)套接字建立),我們就可以使用Socket類(lèi)提供的兩個(gè)方法getInputStream()和getOutputStream()來(lái)作為輸入輸出設(shè)備設(shè)備,實(shí)現(xiàn)服務(wù)器與客戶機(jī)之間的信息交互。服務(wù)器的連接過(guò)程服務(wù)器的工作就是偵聽(tīng)來(lái)自客戶機(jī)的連接客戶端的連接過(guò)程
客戶機(jī)的工作就是要向服務(wù)器發(fā)出連接請(qǐng)求并建立連接。對(duì)客戶機(jī)來(lái)說(shuō),它需要給出要連接的服務(wù)器的IP地址(以便找到該服務(wù)器)以及服務(wù)器的端口號(hào)(以便找到需要連接的服務(wù))。至于客戶機(jī)到底用哪個(gè)端口與服務(wù)器的端口建立連接,是客戶機(jī)上的Java系統(tǒng)決定的。因此,對(duì)于客戶機(jī)來(lái)說(shuō),網(wǎng)絡(luò)編程的步驟是:(1)創(chuàng)建InetAddress對(duì)象,指定服務(wù)器的IP地址:InetAddressaddr=InetAddress.getByName(服務(wù)器的IP地址)(2)創(chuàng)建與服務(wù)器的指定端口的連接:Socketsocket=newSocket(addr,PORT)
客戶端的連接過(guò)程客戶機(jī)的工作就是要向服務(wù)器發(fā)出連接請(qǐng)求簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)1、演示簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)1、演示簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端成員變量設(shè)計(jì)ServerSocketserver=null;Socketsocket=null;BufferedReadercin=null;PrintStreamcout=null;簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端成員變量設(shè)計(jì)ServerSocket簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端事件處理1.打開(kāi)服務(wù)器端口2.等待客戶連接3.構(gòu)建輸入輸出通道4.讀入客戶端發(fā)送的信息簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端事件處理1.打開(kāi)服務(wù)器端口簡(jiǎn)單聊天系統(tǒng)-客戶端成員變量設(shè)計(jì)Socketsocket=null;BufferedReadercin=null;PrintStreamcout=null;簡(jiǎn)單聊天系統(tǒng)-客戶端成員變量設(shè)計(jì)Socketsocket簡(jiǎn)單聊天系統(tǒng)-客戶端事件處理1.獲得服務(wù)器IP2.獲得服務(wù)器端口3.與服務(wù)器連接4.構(gòu)建輸入輸出通道5.向服務(wù)器發(fā)送一條信息簡(jiǎn)單聊天系統(tǒng)-客戶端事件處理1.獲得服務(wù)器IP簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行程序發(fā)現(xiàn):無(wú)法收發(fā)信息。原因:信息未發(fā)送。解決1:客戶端發(fā)送按鈕簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行程序簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題仍然存在問(wèn)題原因:服務(wù)器未進(jìn)行多次接收解決:對(duì)服務(wù)器進(jìn)行10次信息收發(fā)簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題仍然存在問(wèn)題簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題任意多次信息收發(fā)的解決?假死問(wèn)題出現(xiàn)?必須發(fā)送10條信息,才能顯示。對(duì)任意多條,必定永遠(yuǎn)假死。假死問(wèn)題的原因?獨(dú)占資源解決辦法:多線程。演示簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題任意多次信息收發(fā)的解決?Java的多線程機(jī)制
我們都很熟悉多任務(wù)的概念,通常來(lái)說(shuō),多任務(wù)是指通過(guò)CPU時(shí)間分片的方式,讓幾個(gè)程序同時(shí)運(yùn)行。既然程序和程序之間可以同時(shí)運(yùn)行,而程序也無(wú)非是一些代碼,那么,我們可以自然而然地推理出,應(yīng)該也可以通過(guò)CPU時(shí)間分片的方式,讓一個(gè)程序的幾段代碼同時(shí)運(yùn)行,這就是多線程(MultiThreads)。Java作為一種網(wǎng)絡(luò)編程語(yǔ)言,支持多線程機(jī)制。上例中出現(xiàn)假死的原因就是因?yàn)镃PU資源獨(dú)占的緣故。如果我們能夠?qū)⒃斐伞凹偎馈钡哪嵌未a采用多線程機(jī)制來(lái)進(jìn)行,那么就可以讓服務(wù)器不停讀套接字端口的同時(shí),原來(lái)的程序照預(yù)定方式繼續(xù)運(yùn)行。Java的多線程機(jī)制我們都很熟悉多任務(wù)的概念,通常來(lái)說(shuō),多
線程的創(chuàng)建要在程序中對(duì)某些程序片段采用多線程,就必須遵照J(rèn)ava的多線程編程機(jī)制。1.線程的運(yùn)行機(jī)制線程實(shí)際上是程序中的一條執(zhí)行路徑。而多線程則是指程序包含多條執(zhí)行路徑。這樣,在“同一”時(shí)間內(nèi),程序可以存在多條執(zhí)行路徑,“同步”執(zhí)行,以提高程序的執(zhí)行效率。2.線程的創(chuàng)建在Java中,系統(tǒng)提供了一個(gè)Thread類(lèi),用戶通過(guò)繼承Thread類(lèi)的方式,可以將需要的程序段以線程的機(jī)制來(lái)運(yùn)行。其通常做法是:(1)用戶自定義類(lèi),該類(lèi)繼承自Thread類(lèi)。(2)覆蓋(Override)Thread類(lèi)的run方法。在該方法中實(shí)現(xiàn)需要與“主”程序“同步”運(yùn)行的功能。線程的創(chuàng)建要在程序中對(duì)某些程序片段采用多線程,就必須遵照J(rèn)線程的生命周期
對(duì)一個(gè)具體的線程對(duì)象,在其生命周期內(nèi),根據(jù)狀態(tài)的不同,通??梢詤^(qū)分為:1.創(chuàng)建狀態(tài)(new)2.可運(yùn)行狀態(tài)(Runnable)3.阻塞狀態(tài)(Blocked)4.終止?fàn)顟B(tài)線程的生命周期對(duì)一個(gè)具體的線程對(duì)象,在其生命周期內(nèi),根據(jù)狀線程的實(shí)現(xiàn)
目標(biāo):針對(duì)上例,我們希望服務(wù)器端能多次接收客戶端發(fā)送的信息,直到接收到“QUIT”信息才終止連接。解決辦法:我們就可以采用線程的機(jī)制來(lái)實(shí)現(xiàn)
在SingleServer工程的MainFrame類(lèi)中,添加一個(gè)內(nèi)部類(lèi),該內(nèi)部類(lèi)的作用是自定義線程類(lèi),主要實(shí)現(xiàn)服務(wù)器端對(duì)客戶端信息的接收功能。線程的實(shí)現(xiàn)目標(biāo):針對(duì)上例,我們希望服務(wù)器端能多次接收客戶端內(nèi)部線程類(lèi)將需要循環(huán)執(zhí)行的語(yǔ)句塊在線程的run方法中實(shí)現(xiàn)
內(nèi)部線程類(lèi)將需要循環(huán)執(zhí)行的語(yǔ)句塊在線程的run方法中實(shí)現(xiàn) 服務(wù)器端監(jiān)聽(tīng)按鈕事件將實(shí)現(xiàn)收發(fā)功能的代碼用線程來(lái)實(shí)現(xiàn)服務(wù)器端監(jiān)聽(tīng)按鈕事件將實(shí)現(xiàn)收發(fā)功能的代碼用線程來(lái)實(shí)現(xiàn)簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-運(yùn)行運(yùn)行,客戶端可以發(fā)送多條信息,服務(wù)器端顯示。簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-運(yùn)行運(yùn)行,客戶端可以發(fā)送多條信息,服務(wù)器簡(jiǎn)單聊天系統(tǒng)-實(shí)戰(zhàn)演習(xí)
在上例中,我們已經(jīng)實(shí)現(xiàn)服務(wù)器端不停地接收信息,請(qǐng)對(duì)這兩個(gè)工程做修改,實(shí)現(xiàn)如下功能:(1)服務(wù)器在接收到來(lái)自客戶端的非退出信息時(shí),發(fā)送一條“服務(wù)器反饋信息XX”信息到客戶端。(2)服務(wù)器在接收到來(lái)自客戶端的退出信息時(shí),發(fā)送一條“QUIT”信息到客戶端。(3)客戶端能實(shí)時(shí)接收服務(wù)器發(fā)送的信息,當(dāng)接收到“QUIT”信息時(shí),則關(guān)閉套接字連接。簡(jiǎn)單聊天系統(tǒng)-實(shí)戰(zhàn)演習(xí)在上例中,我們已經(jīng)實(shí)現(xiàn)服務(wù)器端不簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-問(wèn)題問(wèn)題:多個(gè)客戶端怎樣同時(shí)與服務(wù)器聯(lián)系?簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-問(wèn)題問(wèn)題:多個(gè)客戶端怎樣同時(shí)與服務(wù)器聯(lián)系多客戶-服務(wù)器信息交互系統(tǒng)上例中之所以只能實(shí)現(xiàn)一個(gè)客戶的連接,是因?yàn)榉?wù)器端的套接字打開(kāi)后,只允許了一個(gè)客戶的連接(serverSocket.accept()只被運(yùn)行了1次)。要實(shí)現(xiàn)多個(gè)客戶的連接,最顯然的方式是讓“等待連接——連接建立——接收信息”程序段重復(fù)運(yùn)行。因此,我們就可以考慮采用多線程的機(jī)制來(lái)實(shí)現(xiàn)。演示多客戶-服務(wù)器信息交互系統(tǒng)上例中之所以只能實(shí)現(xiàn)一個(gè)客戶的連接客戶連接線程的實(shí)現(xiàn)
由于針對(duì)多用戶連接,每個(gè)用戶與服務(wù)器之間都必須形成一條自己的“通道”,以進(jìn)行信息的“收發(fā)”。因此,在服務(wù)器的客戶連接線程中,必須建立服務(wù)器與每個(gè)客戶的套接字。在套接字建立后,通過(guò)創(chuàng)建收發(fā)信息線程,在收發(fā)信息線程中實(shí)現(xiàn)信息的接收與發(fā)送。為實(shí)現(xiàn)信息的接收與發(fā)送,就必須在收發(fā)信息線程中建立套接字的輸入流和輸出流。因此,需要將客戶連接線程中建立的套接字作為參數(shù)傳遞到收發(fā)信息線程中。所以,為實(shí)現(xiàn)多客戶連接,就必須在上例中添加如下的客戶連接線程類(lèi)(內(nèi)部類(lèi)):客戶連接線程的實(shí)現(xiàn)由于針對(duì)多用戶連接,每個(gè)用戶與服務(wù)器之間classConnectSocketextendsThread{publicvoidrun(){//將多用戶連接過(guò)程在run方法中實(shí)現(xiàn)
while(true){//多個(gè)客戶連接循環(huán)
try{ socket=server.accept();//等待客戶連接
}catch(IOExceptione){ jT1.append("用戶連接服務(wù)器出錯(cuò)\n"); } if(socket!=null){ //創(chuàng)建收發(fā)信息線程對(duì)象
ReadMessageThreadreadThread=new
ReadMessageThread(socket); //激活線程
readThread.start(); } }}}客戶連接線程的實(shí)現(xiàn)classConnectSocketextendsTh收發(fā)信息線程的實(shí)現(xiàn)
由于涉及到多個(gè)用戶與服務(wù)器的信息收發(fā),因此,在收發(fā)信息線程中,至少需要三個(gè)成員變量:套接字、輸入流、輸出流,用于構(gòu)建信息收發(fā)的通道。所以,對(duì)上例中的ReadMessageThread類(lèi)應(yīng)做如下的更改:收發(fā)信息線程的實(shí)現(xiàn)由于涉及到多個(gè)用戶與服務(wù)器的信息收發(fā),classReadMessageThreadextendsThread{ BufferedReadercin;//輸入流成員變量
PrintStreamcout;//輸出流成員變量
Socketsocket;//套接字成員變量
/*構(gòu)造器方法,實(shí)現(xiàn)從用戶連接線程中獲得套接字,并利用該套接字實(shí)現(xiàn)輸入流和輸出流的建立*/ ReadMessageThread(Socketsocket){ this.socket=socket; try{ cin=newBufferedReader(newInputStreamReader( this.socket.getInputStream())); cout=newPrintStream(this.socket.getOutputStream()); }catch(IOExceptione){ jT1.append("輸入輸出流建立異常\n"); } } publicvoidrun(){ Stringstr=""; while(true){ try{ str=cin.readLine(); cout.println("服務(wù)器反饋信息"+str); }catch(IOExceptione){ jT1.append("輸入輸出異常\n"); } if(str.equals("QUIT")){ try{ socket.close(); }catch(IOExceptione){ jT1.append("套接字關(guān)閉異常\n"); } break; }else jT1.append(“從客戶端讀入如下的信息:”+str+"\n"); } } }
收發(fā)信息線程的實(shí)現(xiàn)classReadMessageThreadextend多客戶-服務(wù)器信息交互系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行.問(wèn)題:真正系統(tǒng)有用戶信息,相互之間可以發(fā)送信息構(gòu)建真正的多客戶信息廣播系統(tǒng)演示:multiserver2/multiclient2多客戶-服務(wù)器信息交互系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行.多客戶信息廣播系統(tǒng)本節(jié)我們就來(lái)實(shí)現(xiàn)客戶之間通過(guò)服務(wù)器進(jìn)行信息廣播的功能?!皬埲卑l(fā)送信息到服務(wù)器,服務(wù)器將信息轉(zhuǎn)發(fā)到所有與之連接的客戶(“張三”、“李四”),通過(guò)這種形式,就可以實(shí)現(xiàn)客戶之間的信息廣播。在技術(shù)上,我們已經(jīng)實(shí)現(xiàn)了客戶-服務(wù)器之間信息的交互。因此,要實(shí)現(xiàn)上述功能,其關(guān)鍵是如何約定雙方的信息格式,讓服務(wù)器根據(jù)接收的信息來(lái)進(jìn)行不同的處理。多客戶信息廣播系統(tǒng)本節(jié)我們就來(lái)實(shí)現(xiàn)客戶之間通過(guò)服務(wù)器進(jìn)行信息多客戶信息廣播系統(tǒng)-格式約定對(duì)服務(wù)器來(lái)說(shuō),其可能接收到的信息有:(1)客戶請(qǐng)求服務(wù)器的連接信息(2)客戶向服務(wù)器發(fā)送的聊天信息(3)客戶想服務(wù)器發(fā)送的斷開(kāi)請(qǐng)求信息服務(wù)器在接收到上述信息后,應(yīng)做不同的處理。如果接收到的信息是客戶連接信息,則需要提取客戶的名稱,并更新連接客戶列表,并將連接客戶列表廣播到所有客戶端。如果接收到的信息是客戶聊天信息,則需要將信息轉(zhuǎn)發(fā)到每個(gè)客戶端。如果接收到的信息是斷開(kāi)連接信息,則需要發(fā)送同意斷開(kāi)連接信息到對(duì)應(yīng)的客戶端,并關(guān)閉對(duì)應(yīng)的連接套接字,更新連接用戶列表,并將連接客戶列表廣播到所有客戶端。對(duì)客戶端來(lái)說(shuō),其可能接收到的信息有:(1)服務(wù)器發(fā)送的連接客戶列表信息(2)服務(wù)器發(fā)送的聊天信息(3)服務(wù)器發(fā)送的同意斷開(kāi)連接信息。客戶端在接收到上述信息后,應(yīng)做不同的處理。如果是連接客戶列表信息,則將其顯示在客戶端的連接客戶列表信息顯示處。如果是聊天信息,則將其顯示在客戶端的聊天信息顯示處。如果是同意斷開(kāi)信息,則關(guān)閉對(duì)應(yīng)的連接套接字。多客戶信息廣播系統(tǒng)-格式約定對(duì)服務(wù)器來(lái)說(shuō),其可能接收到的信息多客戶信息廣播系統(tǒng)-格式約定依據(jù),我們知道,客戶與服務(wù)器之間需要有如下的信息格式約定:1.客戶向服務(wù)器發(fā)送連接請(qǐng)求的信息格式PEOPLE:客戶名稱其中,PEOPLE是關(guān)鍵區(qū)分字,其后面緊跟客戶名稱,以分號(hào)分隔。2.客戶向服務(wù)器發(fā)送的聊天信息的信息格式MSG:客戶名稱:聊天信息其中,MSG是關(guān)鍵區(qū)分字,其后面緊跟客戶的聊天信息,以分號(hào)分隔。3.客戶向服務(wù)器發(fā)送的請(qǐng)求斷開(kāi)連接的信息格式QUIT其中,QUIT是關(guān)鍵區(qū)分字。4.服務(wù)器向客戶端發(fā)送的連接客戶列表的信息格式PEOPLE:客戶名稱1:客戶名稱2:...:客戶名稱n其中,PEOPLE是關(guān)鍵區(qū)分字,其后面緊跟所有名稱,以分號(hào)分隔。5.服務(wù)器向客戶端廣播的聊天信息的信息格式
MSG:客戶名稱:聊天信息6.服務(wù)器向客戶端發(fā)送的同意斷開(kāi)連接的信息格式QUIT多客戶信息廣播系統(tǒng)-格式約定依據(jù),我們知道,客戶與服務(wù)器之間多客戶信息廣播系統(tǒng)-預(yù)備知識(shí)(信息的分離、存儲(chǔ)與顯示
)服務(wù)器(或客戶端)在接收到相應(yīng)信息后,必須根據(jù)信息的種類(lèi),做相應(yīng)的處理。因此,如何對(duì)收到的信息進(jìn)行分離,是首先需要解決的問(wèn)題。此外,對(duì)服務(wù)器來(lái)說(shuō),需要將連接用戶列表、聊天信息廣播到每一個(gè)客戶端,因此,必須要將每一個(gè)客戶的名稱、與之對(duì)應(yīng)的套接字保存,并提供遍歷的方式,以實(shí)現(xiàn)上述功能。要實(shí)現(xiàn)將客戶列表信息顯示在客戶端,通常的做法可以用JTextArea來(lái)實(shí)現(xiàn),但如果要實(shí)現(xiàn)將信息發(fā)送到指定客戶,就需要選擇客戶名稱,這是JTextArea無(wú)法實(shí)現(xiàn)的。多客戶信息廣播系統(tǒng)-預(yù)備知識(shí)(信息的分離、存儲(chǔ)與顯示)服務(wù)多客戶信息廣播系統(tǒng)-信息分離1.字符串令StringTokenizer在JDK1.4中,系統(tǒng)在java.util包中,提供了一個(gè)字符串令StringTokenizer類(lèi),其主要作用是對(duì)字符串進(jìn)行信息分離。(1)構(gòu)造器方法publicStringTokenizer(String
str,String
delim)將字符串str按給定分隔符號(hào)delim進(jìn)行信息分離,構(gòu)成字符串令對(duì)象。(2)成員方法publicbooleanhasMoreTokens()如果字符串令還有元素,則返回真值。(3)成員方法publicStringnextToken()返回字符串令的下一個(gè)元素。(4)成員方法publicStringnextToken(String
delim)返回字符串令重新以按給定分隔符號(hào)delim進(jìn)行信息分離的下一個(gè)元素。多客戶信息廣播系統(tǒng)-信息分離1.字符串令StringToke多客戶信息廣播系統(tǒng)-用戶存儲(chǔ)在JDK1.4中,系統(tǒng)在java.util包中,提供了一個(gè)向量Vector類(lèi),其主要作用是可以存儲(chǔ)若干的元素(可以是任何類(lèi)型),并提供若干方法,以實(shí)現(xiàn)對(duì)這些元素的遍歷。(1)構(gòu)造器方法publicVector()構(gòu)造一個(gè)向量類(lèi)對(duì)象,其可以存儲(chǔ)任意多個(gè)元素(依據(jù)機(jī)器的內(nèi)存空間)。(2)成員方法publicintsize()返回向量類(lèi)對(duì)象中存儲(chǔ)的元素個(gè)數(shù)。(3)成員方法publicObjectelementAt(inti)返回向量類(lèi)對(duì)象中第i元素。(4)成員方法publicObjectfirstElement()返回向量類(lèi)對(duì)象中第1元素。(5)成員方法publicObjectlastElement()返回向量類(lèi)對(duì)象中最后1個(gè)元素。(6)成員方法publicvoidremoveElementAt(i)移除向量類(lèi)對(duì)象中第i元素。(7)成員方法publicvoidaddElement(Objectc)將c添加到向量類(lèi)對(duì)象。(8)成員方法publicStringtoString()將向量類(lèi)中的每個(gè)元素以字符串形式返回。多客戶信息廣播系統(tǒng)-用戶存儲(chǔ)在JDK1.4中,系統(tǒng)在java多客戶信息廣播系統(tǒng)-用戶顯示在JDK1.4中,系統(tǒng)在javax.swing包中,提供了一個(gè)下拉列表JList類(lèi),其主要作用是實(shí)現(xiàn)按條顯示信息,并能返回所選擇的信息內(nèi)容。(1)構(gòu)造器方法publicJList()構(gòu)造一個(gè)下拉列表類(lèi)對(duì)象,其可以存儲(chǔ)任意多個(gè)元素(依據(jù)機(jī)器的內(nèi)存空間)。(2)成員方法publicvoidsetListData(Vectorvs)將向量vs的每個(gè)元素作為下拉列表的顯示項(xiàng)。(3)成員方法publicObjectgetSelectedValue()返回被選擇的對(duì)象。多客戶信息廣播系統(tǒng)-用戶顯示在JDK1.4中,系統(tǒng)在java多客戶信息廣播系統(tǒng)-服務(wù)器端功能結(jié)構(gòu)
1.多線程機(jī)制在服務(wù)器端,由于需要建立多個(gè)用戶的連接,因此,需要有一個(gè)ConnectSocket線程,其主要工作流程如圖1所示:多客戶信息廣播系統(tǒng)-服務(wù)器端功能結(jié)構(gòu)1.多線程機(jī)制
服務(wù)器與客戶連接后,需要不斷進(jìn)行信息的收發(fā),因此,客戶與服務(wù)器進(jìn)行信息交互也需要用Client線程來(lái)實(shí)現(xiàn)。 在Client的構(gòu)造器中,主要實(shí)現(xiàn)客戶與服務(wù)器的連接通道(輸入流和輸出流),并分離客戶的信息,并將連接信息顯示在服務(wù)器端。
Client接下來(lái)的工作就是不停掃描套接字端口,對(duì)讀入的信息做相應(yīng)的處理。其主要工作流程如圖2所示:多客戶信息廣播系統(tǒng)-服務(wù)器端功能結(jié)構(gòu)
服務(wù)器與客戶連接后,需要不斷進(jìn)行信息的收發(fā),因此,客戶與服對(duì)服務(wù)器來(lái)說(shuō),必須將客戶信息保存,以實(shí)現(xiàn)服務(wù)器與每個(gè)客戶的信息交互。那么,對(duì)服務(wù)器來(lái)說(shuō),到底需要保存客戶的哪些信息呢?顯然,客戶名稱是需要保存的,此外,服務(wù)器與客戶的信息通道(輸入流和輸出流)也需要保存,這樣,才能實(shí)現(xiàn)服務(wù)器通過(guò)訪問(wèn)客戶列表,實(shí)現(xiàn)向每個(gè)客戶發(fā)送消息。因此,我們可以將服務(wù)器—客戶信息交互線程作為用戶列表信息保存起來(lái)。
客戶連接信息的存儲(chǔ)對(duì)服務(wù)器來(lái)說(shuō),必須將客戶信息保存,以實(shí)現(xiàn)服務(wù)器與每個(gè)客戶的信多客戶信息廣播系統(tǒng)-服務(wù)器-客戶連接線程classConnectSocketextendsThread{ Socketsocket; publicvoidrun(){ while(true){ try{ socket=server.accept();//等待客戶連接
}catch(IOExceptione2){ jT1.append("客戶連接失敗\n"); } /*客戶連接成功,定義并實(shí)例化一個(gè)Client線程,每一個(gè)線程對(duì)應(yīng)一個(gè)客戶連接*/ Clientc=newClient(socket); /*將連接的客戶添加到客戶列表存儲(chǔ)clients中*/ clients.addElement(c); /*測(cè)該用戶名稱是否存在,如不存在,則啟動(dòng)線程,實(shí)現(xiàn)客戶與服務(wù)器的信息交互通道*/ if(checkName(c)){ //啟動(dòng)線程
c.start(); /*向每個(gè)客戶端更新客戶列表信息*/ notifyRoom(); }else{ disconnect(c); } } }}多客戶信息廣播系統(tǒng)-服務(wù)器-客戶連接線程classConn多客戶信息廣播系統(tǒng)-服務(wù)器-客戶端信息交互線程見(jiàn)教材多客戶信息廣播系統(tǒng)-服務(wù)器-客戶端信息交互線程見(jiàn)教材多客戶信息廣播系統(tǒng)-客戶名檢測(cè)成員方法
該方法作為MultiServer1類(lèi)的成員方法,主要功能是檢測(cè)登陸的客戶名是否已被其他已登陸的客戶所占用。由于用戶登陸成功后,將所有信息已保存在Client線程對(duì)象中。因此,我們可以比較新建立的Client線程對(duì)象的客戶名稱是否和已存在的Client線程對(duì)象的客戶名稱是否重復(fù)而返回boolean值,供調(diào)用該方法的程序段進(jìn)行處理。(見(jiàn)教材)多客戶信息廣播系統(tǒng)-客戶名檢測(cè)成員方法該方法作為Multi多客戶信息廣播系統(tǒng)-客戶列表信息發(fā)送成員方法
該方法作為MultiServer1類(lèi)的成員方法,主要功能是將已連接的客戶名稱發(fā)送到所有客戶端。(見(jiàn)教材)多客戶信息廣播系統(tǒng)-客戶列表信息發(fā)送成員方法該方法作為Mu多客戶信息廣播系統(tǒng)-息廣播成員方法
該方法作為MultiServer1類(lèi)的成員方法,主要功能是將要發(fā)送的信息發(fā)送到所有客戶端。(見(jiàn)教材)多客戶信息廣播系統(tǒng)-息廣播成員方法該方法作為MultiSe多客戶信息廣播系統(tǒng)-斷開(kāi)服務(wù)器-客戶連接方法
該方法作為MultiServer1類(lèi)的成員方法,主要功能是斷開(kāi)某一個(gè)特定的服務(wù)器—客戶交互信息線程,并清除與之對(duì)應(yīng)的用戶列表信息。(見(jiàn)教材)多客戶信息廣播系統(tǒng)-斷開(kāi)服務(wù)器-客戶連接方法該方法作為Mu多客戶信息廣播系統(tǒng)-客戶器端功能結(jié)構(gòu)
客戶端按鈕功能客戶端有3個(gè)按鈕,每個(gè)按鈕都響應(yīng)不同的功能,其主要工作流程如圖所示:多客戶信息廣播系統(tǒng)-客戶器端功能結(jié)構(gòu)客戶端按鈕功能讀取服務(wù)器發(fā)送信息線程客戶端在讀取信息后,必須對(duì)信息的類(lèi)型進(jìn)行分析,根據(jù)不同信息類(lèi)型做相應(yīng)處理,其主要工作流程如圖5所示:讀取服務(wù)器發(fā)送信息線程多客戶信息廣播系統(tǒng)-讀取服務(wù)器發(fā)送信息線程ReadMessageThread類(lèi)作為MultiClient類(lèi)的內(nèi)部類(lèi),主要實(shí)現(xiàn)如圖所示的功能
(見(jiàn)教材)多客戶信息廣播系統(tǒng)-讀取服務(wù)器發(fā)送信息線程ReadMessa多客戶信息交流系統(tǒng)請(qǐng)對(duì)上例進(jìn)行修改,實(shí)現(xiàn)“基于TCP協(xié)議的多客戶信息交流系統(tǒng)”。(1)客戶端界面如圖6所示。(2)客戶端發(fā)送信息可以選擇廣播或特定客戶。(3)如選擇廣播,則將信息轉(zhuǎn)發(fā)到所有客戶端。(4)如選擇“特定客戶”,則將信息只發(fā)送到選擇的客戶。提示:要實(shí)現(xiàn)廣播和特定發(fā)送,就需要對(duì)客戶端發(fā)送到服務(wù)器端的信息協(xié)議做調(diào)整,可以約定為:若為廣播,則信息格式為“MSG:BROAD:發(fā)送客戶名稱:發(fā)送的信息”;若為特定發(fā)送,則信息格式為“MSG:SINGLE:接收客戶名稱:發(fā)送客戶名稱:發(fā)送的信息”。多客戶信息交流系統(tǒng)請(qǐng)對(duì)上例進(jìn)行修改,實(shí)現(xiàn)“基于TCP協(xié)議的多多客戶信息交流系統(tǒng)多客戶信息交流系統(tǒng)UDP協(xié)議基礎(chǔ)-UDP協(xié)議與TCP協(xié)議的異同UDP不存在“真實(shí)”連接UDP不打開(kāi)端口等待連接UDP協(xié)議基礎(chǔ)-UDP協(xié)議與TCP協(xié)議的異同UDP不存在UDP協(xié)議基礎(chǔ)-UDP服務(wù)器端的連接過(guò)程(1)在服務(wù)器的指定端口上創(chuàng)建DatagramSocket數(shù)據(jù)報(bào)套接字對(duì)象,該對(duì)象用于收發(fā)數(shù)據(jù)報(bào)。DatagramSocketsocket=newDatagramSocket(INPORT)(2)創(chuàng)建DatagramPacket數(shù)據(jù)報(bào)包對(duì)象,用來(lái)存儲(chǔ)接收到的數(shù)據(jù)報(bào)包。DatagramPacketdp=newDatagramPacket(buf,buf.length),其中,buf為字節(jié)數(shù)組
(3)要接收數(shù)據(jù),通過(guò)數(shù)據(jù)報(bào)套接字對(duì)象的receive()方法接收1個(gè)數(shù)據(jù)包到創(chuàng)建的數(shù)據(jù)報(bào)包對(duì)象dp中。socket.receive(dp)(4)要發(fā)送數(shù)據(jù),將數(shù)據(jù)組合成數(shù)據(jù)報(bào)包對(duì)象,通過(guò)數(shù)據(jù)報(bào)套接字對(duì)象的send()發(fā)放將數(shù)據(jù)發(fā)送。注意,數(shù)據(jù)組合成數(shù)據(jù)報(bào)包對(duì)象時(shí),要給出對(duì)方的IP地址和端口號(hào)。UDP協(xié)議基礎(chǔ)-UDP服務(wù)器端的連接過(guò)程(1)在服務(wù)器的指定UDP協(xié)議基礎(chǔ)-UDP客戶端的連接過(guò)程(1)在客戶機(jī)上創(chuàng)建DatagramSocket數(shù)據(jù)報(bào)套接字對(duì)象,該對(duì)象用于收發(fā)數(shù)據(jù)報(bào)。系統(tǒng)將決定采用哪個(gè)端口。DatagramSocketsocket=newDatagramSocket()(2)創(chuàng)建DatagramPacket數(shù)據(jù)報(bào)包對(duì)象,用來(lái)存儲(chǔ)接收到的數(shù)據(jù)報(bào)包。DatagramPacketdp=newDatagramPacket(buf,buf.length),其中,buf為字節(jié)數(shù)組
(3)要接收數(shù)據(jù),通過(guò)數(shù)據(jù)報(bào)套接字對(duì)象的receive()方法接收1個(gè)數(shù)據(jù)包到創(chuàng)建的數(shù)據(jù)報(bào)包對(duì)象dp中。socket.receive(dp);(4)要發(fā)送數(shù)據(jù),將數(shù)據(jù)組合成數(shù)據(jù)報(bào)包對(duì)象,通過(guò)數(shù)據(jù)報(bào)套接字對(duì)象的send()發(fā)放將數(shù)據(jù)發(fā)送。注意,數(shù)據(jù)組合成數(shù)據(jù)報(bào)包對(duì)象時(shí),要給出對(duì)方的IP地址和端口號(hào)。
UDP協(xié)議基礎(chǔ)-UDP客戶端的連接過(guò)程(1)在客戶機(jī)上創(chuàng)建網(wǎng)絡(luò)編程基礎(chǔ)網(wǎng)絡(luò)編程基礎(chǔ)網(wǎng)絡(luò)聊天室范例演示需要解決的問(wèn)題1)如何與對(duì)方機(jī)器進(jìn)行連接2)如何找到對(duì)應(yīng)的應(yīng)用程序3)對(duì)收到的信息怎樣實(shí)現(xiàn)是廣播還是一對(duì)一?網(wǎng)絡(luò)聊天室范例演示網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2Internet上互相通信的計(jì)算機(jī)采用的協(xié)議是TCP協(xié)議或者UDP協(xié)議,它們的結(jié)構(gòu)類(lèi)似于:網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2Internet上互相通信的網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2TCP是傳輸控制協(xié)議,也稱為“基于數(shù)據(jù)流的套接字”,根據(jù)該協(xié)議的設(shè)計(jì)宗旨,它具有高度的可靠性,而且能保證數(shù)據(jù)順利到達(dá)目的地。換言之,它允許重傳那些由于各種原因半路“走失”的數(shù)據(jù)。而且收到字節(jié)的順序與它們發(fā)出的順序是一樣的。TCP的高可靠性需要付出的代價(jià)是:高開(kāi)銷(xiāo)(需要有很多的信息用于控制信息)。而UDP稱為用戶數(shù)據(jù)報(bào)協(xié)議,它并不刻意追求數(shù)據(jù)報(bào)會(huì)完全發(fā)送出去,也不能擔(dān)保抵達(dá)的順序與它們發(fā)出時(shí)一樣。因此,UDP被認(rèn)為是一種不可靠協(xié)議。但是,它的速度快,對(duì)于某些應(yīng)用來(lái)說(shuō)(例如聲音),如果速度并質(zhì)量更重要,就可以采用UDP協(xié)議。大多數(shù)互聯(lián)網(wǎng)游戲也是采用UDP協(xié)議。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2TCP是傳輸控制協(xié)議,也稱為網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2機(jī)器標(biāo)識(shí)為了分辨出網(wǎng)絡(luò)上的每一臺(tái)機(jī)器,必須有一種機(jī)制能獨(dú)一無(wú)二地標(biāo)識(shí)出網(wǎng)絡(luò)內(nèi)的每臺(tái)機(jī)器。這可以通過(guò)IP地址來(lái)實(shí)現(xiàn)。IP地址以兩種形式存在:直接IP地址(如)域名()。
網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2機(jī)器標(biāo)識(shí)網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2服務(wù)器和客戶機(jī)網(wǎng)絡(luò)最基本的精神是讓兩臺(tái)計(jì)算機(jī)連接在一起,并相互“溝通”。一旦兩臺(tái)計(jì)算機(jī)發(fā)現(xiàn)了對(duì)方,就可以開(kāi)始溝通,但它們?cè)鯓硬拍堋鞍l(fā)現(xiàn)”對(duì)方呢??jī)膳_(tái)計(jì)算機(jī)要發(fā)現(xiàn)對(duì)方,通常需要其中一臺(tái)扮演“服務(wù)器”的角色,另一臺(tái)扮演“客戶機(jī)”的角色。客戶機(jī)用來(lái)發(fā)出連接請(qǐng)求,而服務(wù)器用來(lái)等待連接請(qǐng)求。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2服務(wù)器和客戶機(jī)網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2客戶機(jī)發(fā)出連接請(qǐng)求到服務(wù)器(通過(guò)IP地址),請(qǐng)求信息在網(wǎng)絡(luò)上傳輸,當(dāng)服務(wù)器在接到連接請(qǐng)求并確認(rèn)后,建立與客戶機(jī)的連接。一旦連接建立好,服務(wù)器和客戶機(jī)之間就變成了一種雙向通信,那么無(wú)論是對(duì)服務(wù)器端還是對(duì)客戶機(jī)端來(lái)說(shuō),連接就變成了一個(gè)IO數(shù)據(jù)流對(duì)象。從這是開(kāi)始,我們就可以象讀寫(xiě)一個(gè)普通的文件一樣來(lái)對(duì)待連接。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2客戶機(jī)發(fā)出連接請(qǐng)求到服務(wù)器(網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2端口有些時(shí)候,一個(gè)IP地址并不足以完整標(biāo)識(shí)一個(gè)服務(wù)器。這是由于在一臺(tái)計(jì)算機(jī)中,往往運(yùn)行著多個(gè)服務(wù)器(即不同的網(wǎng)絡(luò)應(yīng)用程序)。為了標(biāo)識(shí)是哪個(gè)服務(wù)器,就需要用到一個(gè)端口。例如,通常來(lái)說(shuō)HTTP采用的是80端口,F(xiàn)TP采用的是21端口。端口并不是機(jī)器上一個(gè)物理上存在的場(chǎng)所,而是一種軟件抽象(主要是為了表達(dá)的方便)??蛻舫绦蛑廊绾瓮ㄟ^(guò)機(jī)器的IP地址同服務(wù)器連接,但怎樣才能同自己真正需要的那種服務(wù)連接呢(一般每個(gè)端口都運(yùn)行著一種服務(wù),一臺(tái)機(jī)器可能提供了多種服務(wù),例如HTTP、FTP)?端口在這里扮演了重要的角色,它是必需的一種二級(jí)定址措施。也就是說(shuō),我們請(qǐng)求一個(gè)特定的端口,就是請(qǐng)求與那個(gè)端口編號(hào)關(guān)聯(lián)的服務(wù)。系統(tǒng)保留了使用端口1到端口1024的權(quán)利,所以,在我們?cè)O(shè)計(jì)網(wǎng)絡(luò)通信程序時(shí),一般不應(yīng)站用這些端口。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2端口網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2套接字
Socket套接字也是一種軟件形式的抽象。用于表達(dá)兩臺(tái)機(jī)器間一個(gè)連接的“通道”。針對(duì)一個(gè)特定的連接,每臺(tái)機(jī)器上都有一個(gè)“套接字”,通過(guò)“套接字”,兩臺(tái)機(jī)器之間就形成了一條“虛擬”的通道。網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)—解決問(wèn)題1和2套接字Java的網(wǎng)絡(luò)編程類(lèi)JDK提供了1個(gè)包,在該包中,主要包含如下的幾個(gè)類(lèi):1.Java中IP地址的表示(InetAddress類(lèi))
包中提供了一個(gè)InetAddress類(lèi),該類(lèi)用于表示一個(gè)IP地址。它常用的方法有:(1)publicstaticInetAddressgetByName(String
host)返回字符串host所表示的IP地址。(2)publicstaticInetAddressgetLocalHost()返回本機(jī)IP地址(如果你的機(jī)器設(shè)置了IP地址,則返回你自己的IP,否則返回默認(rèn)的IP地址:)。Java的網(wǎng)絡(luò)編程類(lèi)JDK提供了1個(gè)包,在該Java的網(wǎng)絡(luò)編程類(lèi)2.服務(wù)器端口打開(kāi)(ServerSocket類(lèi))ServerSocket類(lèi)用于在服務(wù)器端打開(kāi)某一個(gè)端口,等待客戶端的連接請(qǐng)求,它常用的方法有:(1)構(gòu)造器方法publicServerSocket(int
port)用于打開(kāi)服務(wù)器port端口。(2)publicSocketaccept()用于等待客戶連接,當(dāng)連接成功時(shí),形成一個(gè)套接字對(duì)象。(3)publicvoidclose()關(guān)閉用戶連接。Java的網(wǎng)絡(luò)編程類(lèi)2.服務(wù)器端口打開(kāi)(ServerSockJava的網(wǎng)絡(luò)編程類(lèi)3.套接字建立(Socket類(lèi))
Socket類(lèi)用于套接字的建立。它常用的方法有:(1)構(gòu)造器方法publicSocket(InetAddress
address,int
port)用于客戶端與指定的服務(wù)器IP地址及服務(wù)器端口進(jìn)行套接字連接。(2)publicvoidclose()關(guān)閉用戶連接。(3)publicInputStreamgetInputStream()從套接字返回一個(gè)輸入流(4)publicOutputStreamgetOutputStream()從套接字返回一個(gè)輸出流Java的網(wǎng)絡(luò)編程類(lèi)3.套接字建立(Socket類(lèi))服務(wù)器的連接過(guò)程
服務(wù)器的工作就是偵聽(tīng)來(lái)自客戶機(jī)的連接請(qǐng)求并建立連接。因此,對(duì)于服務(wù)器端來(lái)說(shuō),網(wǎng)絡(luò)編程的步驟是:(1)創(chuàng)建ServerSocket對(duì)象:ServerSocketserver=newServerSocket(PORT),其中,PORT是指服務(wù)器打開(kāi)哪個(gè)端口來(lái)等待和建立連接。(2)等待連接:Socketsocket=server.accept(),連接形成是以套接字來(lái)表示的,一旦連接成功,就會(huì)在服務(wù)器—客戶機(jī)之間形成一個(gè)套接字。(3)一旦連接建立好(即服務(wù)器—客戶機(jī)套接字建立),我們就可以使用Socket類(lèi)提供的兩個(gè)方法getInputStream()和getOutputStream()來(lái)作為輸入輸出設(shè)備設(shè)備,實(shí)現(xiàn)服務(wù)器與客戶機(jī)之間的信息交互。服務(wù)器的連接過(guò)程服務(wù)器的工作就是偵聽(tīng)來(lái)自客戶機(jī)的連接客戶端的連接過(guò)程
客戶機(jī)的工作就是要向服務(wù)器發(fā)出連接請(qǐng)求并建立連接。對(duì)客戶機(jī)來(lái)說(shuō),它需要給出要連接的服務(wù)器的IP地址(以便找到該服務(wù)器)以及服務(wù)器的端口號(hào)(以便找到需要連接的服務(wù))。至于客戶機(jī)到底用哪個(gè)端口與服務(wù)器的端口建立連接,是客戶機(jī)上的Java系統(tǒng)決定的。因此,對(duì)于客戶機(jī)來(lái)說(shuō),網(wǎng)絡(luò)編程的步驟是:(1)創(chuàng)建InetAddress對(duì)象,指定服務(wù)器的IP地址:InetAddressaddr=InetAddress.getByName(服務(wù)器的IP地址)(2)創(chuàng)建與服務(wù)器的指定端口的連接:Socketsocket=newSocket(addr,PORT)
客戶端的連接過(guò)程客戶機(jī)的工作就是要向服務(wù)器發(fā)出連接請(qǐng)求簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)1、演示簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)1、演示簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端成員變量設(shè)計(jì)ServerSocketserver=null;Socketsocket=null;BufferedReadercin=null;PrintStreamcout=null;簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端成員變量設(shè)計(jì)ServerSocket簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端事件處理1.打開(kāi)服務(wù)器端口2.等待客戶連接3.構(gòu)建輸入輸出通道4.讀入客戶端發(fā)送的信息簡(jiǎn)單聊天系統(tǒng)-服務(wù)器端事件處理1.打開(kāi)服務(wù)器端口簡(jiǎn)單聊天系統(tǒng)-客戶端成員變量設(shè)計(jì)Socketsocket=null;BufferedReadercin=null;PrintStreamcout=null;簡(jiǎn)單聊天系統(tǒng)-客戶端成員變量設(shè)計(jì)Socketsocket簡(jiǎn)單聊天系統(tǒng)-客戶端事件處理1.獲得服務(wù)器IP2.獲得服務(wù)器端口3.與服務(wù)器連接4.構(gòu)建輸入輸出通道5.向服務(wù)器發(fā)送一條信息簡(jiǎn)單聊天系統(tǒng)-客戶端事件處理1.獲得服務(wù)器IP簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行程序發(fā)現(xiàn):無(wú)法收發(fā)信息。原因:信息未發(fā)送。解決1:客戶端發(fā)送按鈕簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行程序簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題仍然存在問(wèn)題原因:服務(wù)器未進(jìn)行多次接收解決:對(duì)服務(wù)器進(jìn)行10次信息收發(fā)簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題仍然存在問(wèn)題簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題任意多次信息收發(fā)的解決?假死問(wèn)題出現(xiàn)?必須發(fā)送10條信息,才能顯示。對(duì)任意多條,必定永遠(yuǎn)假死。假死問(wèn)題的原因?獨(dú)占資源解決辦法:多線程。演示簡(jiǎn)單聊天系統(tǒng)-運(yùn)行與問(wèn)題任意多次信息收發(fā)的解決?Java的多線程機(jī)制
我們都很熟悉多任務(wù)的概念,通常來(lái)說(shuō),多任務(wù)是指通過(guò)CPU時(shí)間分片的方式,讓幾個(gè)程序同時(shí)運(yùn)行。既然程序和程序之間可以同時(shí)運(yùn)行,而程序也無(wú)非是一些代碼,那么,我們可以自然而然地推理出,應(yīng)該也可以通過(guò)CPU時(shí)間分片的方式,讓一個(gè)程序的幾段代碼同時(shí)運(yùn)行,這就是多線程(MultiThreads)。Java作為一種網(wǎng)絡(luò)編程語(yǔ)言,支持多線程機(jī)制。上例中出現(xiàn)假死的原因就是因?yàn)镃PU資源獨(dú)占的緣故。如果我們能夠?qū)⒃斐伞凹偎馈钡哪嵌未a采用多線程機(jī)制來(lái)進(jìn)行,那么就可以讓服務(wù)器不停讀套接字端口的同時(shí),原來(lái)的程序照預(yù)定方式繼續(xù)運(yùn)行。Java的多線程機(jī)制我們都很熟悉多任務(wù)的概念,通常來(lái)說(shuō),多
線程的創(chuàng)建要在程序中對(duì)某些程序片段采用多線程,就必須遵照J(rèn)ava的多線程編程機(jī)制。1.線程的運(yùn)行機(jī)制線程實(shí)際上是程序中的一條執(zhí)行路徑。而多線程則是指程序包含多條執(zhí)行路徑。這樣,在“同一”時(shí)間內(nèi),程序可以存在多條執(zhí)行路徑,“同步”執(zhí)行,以提高程序的執(zhí)行效率。2.線程的創(chuàng)建在Java中,系統(tǒng)提供了一個(gè)Thread類(lèi),用戶通過(guò)繼承Thread類(lèi)的方式,可以將需要的程序段以線程的機(jī)制來(lái)運(yùn)行。其通常做法是:(1)用戶自定義類(lèi),該類(lèi)繼承自Thread類(lèi)。(2)覆蓋(Override)Thread類(lèi)的run方法。在該方法中實(shí)現(xiàn)需要與“主”程序“同步”運(yùn)行的功能。線程的創(chuàng)建要在程序中對(duì)某些程序片段采用多線程,就必須遵照J(rèn)線程的生命周期
對(duì)一個(gè)具體的線程對(duì)象,在其生命周期內(nèi),根據(jù)狀態(tài)的不同,通??梢詤^(qū)分為:1.創(chuàng)建狀態(tài)(new)2.可運(yùn)行狀態(tài)(Runnable)3.阻塞狀態(tài)(Blocked)4.終止?fàn)顟B(tài)線程的生命周期對(duì)一個(gè)具體的線程對(duì)象,在其生命周期內(nèi),根據(jù)狀線程的實(shí)現(xiàn)
目標(biāo):針對(duì)上例,我們希望服務(wù)器端能多次接收客戶端發(fā)送的信息,直到接收到“QUIT”信息才終止連接。解決辦法:我們就可以采用線程的機(jī)制來(lái)實(shí)現(xiàn)
在SingleServer工程的MainFrame類(lèi)中,添加一個(gè)內(nèi)部類(lèi),該內(nèi)部類(lèi)的作用是自定義線程類(lèi),主要實(shí)現(xiàn)服務(wù)器端對(duì)客戶端信息的接收功能。線程的實(shí)現(xiàn)目標(biāo):針對(duì)上例,我們希望服務(wù)器端能多次接收客戶端內(nèi)部線程類(lèi)將需要循環(huán)執(zhí)行的語(yǔ)句塊在線程的run方法中實(shí)現(xiàn)
內(nèi)部線程類(lèi)將需要循環(huán)執(zhí)行的語(yǔ)句塊在線程的run方法中實(shí)現(xiàn) 服務(wù)器端監(jiān)聽(tīng)按鈕事件將實(shí)現(xiàn)收發(fā)功能的代碼用線程來(lái)實(shí)現(xiàn)服務(wù)器端監(jiān)聽(tīng)按鈕事件將實(shí)現(xiàn)收發(fā)功能的代碼用線程來(lái)實(shí)現(xiàn)簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-運(yùn)行運(yùn)行,客戶端可以發(fā)送多條信息,服務(wù)器端顯示。簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-運(yùn)行運(yùn)行,客戶端可以發(fā)送多條信息,服務(wù)器簡(jiǎn)單聊天系統(tǒng)-實(shí)戰(zhàn)演習(xí)
在上例中,我們已經(jīng)實(shí)現(xiàn)服務(wù)器端不停地接收信息,請(qǐng)對(duì)這兩個(gè)工程做修改,實(shí)現(xiàn)如下功能:(1)服務(wù)器在接收到來(lái)自客戶端的非退出信息時(shí),發(fā)送一條“服務(wù)器反饋信息XX”信息到客戶端。(2)服務(wù)器在接收到來(lái)自客戶端的退出信息時(shí),發(fā)送一條“QUIT”信息到客戶端。(3)客戶端能實(shí)時(shí)接收服務(wù)器發(fā)送的信息,當(dāng)接收到“QUIT”信息時(shí),則關(guān)閉套接字連接。簡(jiǎn)單聊天系統(tǒng)-實(shí)戰(zhàn)演習(xí)在上例中,我們已經(jīng)實(shí)現(xiàn)服務(wù)器端不簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-問(wèn)題問(wèn)題:多個(gè)客戶端怎樣同時(shí)與服務(wù)器聯(lián)系?簡(jiǎn)單聊天系統(tǒng)的實(shí)現(xiàn)-問(wèn)題問(wèn)題:多個(gè)客戶端怎樣同時(shí)與服務(wù)器聯(lián)系多客戶-服務(wù)器信息交互系統(tǒng)上例中之所以只能實(shí)現(xiàn)一個(gè)客戶的連接,是因?yàn)榉?wù)器端的套接字打開(kāi)后,只允許了一個(gè)客戶的連接(serverSocket.accept()只被運(yùn)行了1次)。要實(shí)現(xiàn)多個(gè)客戶的連接,最顯然的方式是讓“等待連接——連接建立——接收信息”程序段重復(fù)運(yùn)行。因此,我們就可以考慮采用多線程的機(jī)制來(lái)實(shí)現(xiàn)。演示多客戶-服務(wù)器信息交互系統(tǒng)上例中之所以只能實(shí)現(xiàn)一個(gè)客戶的連接客戶連接線程的實(shí)現(xiàn)
由于針對(duì)多用戶連接,每個(gè)用戶與服務(wù)器之間都必須形成一條自己的“通道”,以進(jìn)行信息的“收發(fā)”。因此,在服務(wù)器的客戶連接線程中,必須建立服務(wù)器與每個(gè)客戶的套接字。在套接字建立后,通過(guò)創(chuàng)建收發(fā)信息線程,在收發(fā)信息線程中實(shí)現(xiàn)信息的接收與發(fā)送。為實(shí)現(xiàn)信息的接收與發(fā)送,就必須在收發(fā)信息線程中建立套接字的輸入流和輸出流。因此,需要將客戶連接線程中建立的套接字作為參數(shù)傳遞到收發(fā)信息線程中。所以,為實(shí)現(xiàn)多客戶連接,就必須在上例中添加如下的客戶連接線程類(lèi)(內(nèi)部類(lèi)):客戶連接線程的實(shí)現(xiàn)由于針對(duì)多用戶連接,每個(gè)用戶與服務(wù)器之間classConnectSocketextendsThread{publicvoidrun(){//將多用戶連接過(guò)程在run方法中實(shí)現(xiàn)
while(true){//多個(gè)客戶連接循環(huán)
try{ socket=server.accept();//等待客戶連接
}catch(IOExceptione){ jT1.append("用戶連接服務(wù)器出錯(cuò)\n"); } if(socket!=null){ //創(chuàng)建收發(fā)信息線程對(duì)象
ReadMessageThreadreadThread=new
ReadMessageThread(socket); //激活線程
readThread.start(); } }}}客戶連接線程的實(shí)現(xiàn)classConnectSocketextendsTh收發(fā)信息線程的實(shí)現(xiàn)
由于涉及到多個(gè)用戶與服務(wù)器的信息收發(fā),因此,在收發(fā)信息線程中,至少需要三個(gè)成員變量:套接字、輸入流、輸出流,用于構(gòu)建信息收發(fā)的通道。所以,對(duì)上例中的ReadMessageThread類(lèi)應(yīng)做如下的更改:收發(fā)信息線程的實(shí)現(xiàn)由于涉及到多個(gè)用戶與服務(wù)器的信息收發(fā),classReadMessageThreadextendsThread{ BufferedReadercin;//輸入流成員變量
PrintStreamcout;//輸出流成員變量
Socketsocket;//套接字成員變量
/*構(gòu)造器方法,實(shí)現(xiàn)從用戶連接線程中獲得套接字,并利用該套接字實(shí)現(xiàn)輸入流和輸出流的建立*/ ReadMessageThread(Socketsocket){ this.socket=socket; try{ cin=newBufferedReader(newInputStreamReader( this.socket.getInputStream())); cout=newPrintStream(this.socket.getOutputStream()); }catch(IOExceptione){ jT1.append("輸入輸出流建立異常\n"); } } publicvoidrun(){ Stringstr=""; while(true){ try{ str=cin.readLine(); cout.println("服務(wù)器反饋信息"+str); }catch(IOExceptione){ jT1.append("輸入輸出異常\n"); } if(str.equals("QUIT")){ try{ socket.close(); }catch(IOExceptione){ jT1.append("套接字關(guān)閉異常\n"); } break; }else jT1.append(“從客戶端讀入如下的信息:”+str+"\n"); } } }
收發(fā)信息線程的實(shí)現(xiàn)classReadMessageThreadextend多客戶-服務(wù)器信息交互系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行.問(wèn)題:真正系統(tǒng)有用戶信息,相互之間可以發(fā)送信息構(gòu)建真正的多客戶信息廣播系統(tǒng)演示:multiserver2/multiclient2多客戶-服務(wù)器信息交互系統(tǒng)-運(yùn)行與問(wèn)題運(yùn)行.多客戶信息廣播系統(tǒng)本節(jié)我們就來(lái)實(shí)現(xiàn)客戶之間通過(guò)服務(wù)器進(jìn)行信息廣播的功能?!皬埲卑l(fā)送信息到服務(wù)器,服務(wù)器將信息轉(zhuǎn)發(fā)到所有與之連接的客戶(“張三”、“李四”),通過(guò)這種形式,就可以實(shí)現(xiàn)客戶之間的信息廣播。在技術(shù)上,我們已經(jīng)實(shí)現(xiàn)了客戶-服務(wù)器之間信息的交互。因此,要實(shí)現(xiàn)上述功能,其關(guān)鍵是如何約定雙方的信息格式,讓服務(wù)器根據(jù)接收的信息來(lái)進(jìn)行不同的處理。多客戶信息廣播系統(tǒng)本節(jié)我們就來(lái)實(shí)現(xiàn)客戶之間通過(guò)服務(wù)器進(jìn)行信息多客戶信息廣播系統(tǒng)-格式約定對(duì)服務(wù)器來(lái)說(shuō),其可能接收到的信息有:(1)客戶請(qǐng)求服務(wù)器的連接信息(2)客戶向服務(wù)器發(fā)送的聊天信息(3)客戶想服務(wù)器發(fā)送的斷開(kāi)請(qǐng)求信息服務(wù)器在接收到上述信息后,應(yīng)做不同的處理。如果接收到的信息是客戶連接信息,則需要提取客戶的名稱,并更新連接客戶列表,并將連接客戶列表廣播到所有客戶端。如果接收到的信息是客戶聊天信息,則需要將信息轉(zhuǎn)發(fā)到每個(gè)客戶端。如果接收到的信息是斷開(kāi)連接信息,則需要發(fā)送同意斷開(kāi)連接信息到對(duì)應(yīng)的客戶端,并關(guān)閉對(duì)應(yīng)的連接套接字,更新連接用戶列表,并將連接客戶列表廣播到所有客戶端。對(duì)客戶端來(lái)說(shuō),其可能接收到的信息有:(1)服務(wù)器發(fā)送的連接客戶列表信息(2)服務(wù)器發(fā)送的聊天信息(3)服務(wù)器發(fā)送的同意斷開(kāi)連接信息??蛻舳嗽诮邮盏缴鲜鲂畔⒑?,應(yīng)做不同的處理。如果是連接客戶列表信息,則將其顯示在客戶端的連接客戶列表信息顯示處。如果是聊天信息,則將其顯示在客戶端的聊天信息顯示處。如果是同意斷開(kāi)信息,則關(guān)閉對(duì)應(yīng)的連接套接字。多客戶信息廣播系統(tǒng)-格式約定對(duì)服務(wù)器來(lái)說(shuō),其可能接收到的信息多客戶信息廣播系統(tǒng)-格式約定依據(jù),我們知道,客戶與服務(wù)器之間需要有如下的信息格式約定:1.客戶向服務(wù)器發(fā)送連接請(qǐng)求的信息格式PEOPLE:客戶名稱其中,PEOPLE是關(guān)鍵區(qū)分字,其后面緊跟客戶名稱,以分號(hào)分隔。2.客戶向服務(wù)器發(fā)送的聊天信息的信息格式MSG:客戶名稱:聊天信息其中,MSG是關(guān)鍵區(qū)分字,其后面緊跟客戶的聊天信息,以分號(hào)分隔。3.客戶向服務(wù)器發(fā)送的請(qǐng)求斷開(kāi)連接的信息格式QUIT其中,QUIT是關(guān)鍵區(qū)分字。4.服務(wù)器向客戶端發(fā)送的連接客戶列表的信息格式PEOPLE:客戶名稱1:客戶名稱2:...:客戶名稱n其中,PEOPLE是關(guān)鍵區(qū)分字,其后面緊跟所有名稱,以分號(hào)分隔。5.服務(wù)器向客戶端廣播的聊天信息的信息格式
MSG:客戶名稱:聊天信息6.服務(wù)器向客戶端發(fā)送的同意斷開(kāi)連接的信息格式QUIT多客戶信息廣播系統(tǒng)-格式約定依據(jù),我們知道,客戶與服務(wù)器之間多客戶信息廣播系統(tǒng)-預(yù)備知識(shí)(信息的分離、存儲(chǔ)與顯示
)服務(wù)器(或客戶端)在接收到相應(yīng)信息后,必須根據(jù)信息的種類(lèi),做相應(yīng)的處理。因此,如何對(duì)收到的信息進(jìn)行分離,是首先需要解決的問(wèn)題。此外,對(duì)服務(wù)器來(lái)說(shuō),需要將連接用戶列表、聊天信息廣播到每一個(gè)客戶端,因此,必須要將每一個(gè)客戶的名稱、與之對(duì)應(yīng)的套接字保存,并提供遍歷的方式,以實(shí)現(xiàn)上述功能。要實(shí)現(xiàn)將客戶列表信息顯示在客戶端,通常的做法可以用JTextArea來(lái)實(shí)現(xiàn),但如果要實(shí)現(xiàn)將信息發(fā)送到指定客戶,就需要選擇客戶名稱,這是JTextArea無(wú)法實(shí)現(xiàn)的。多客戶信息廣播系統(tǒng)-預(yù)備知識(shí)(信息的分離、存儲(chǔ)與顯示)服務(wù)多客戶信息廣播系統(tǒng)-信息分離1.字符串令StringTokenizer在JDK1.4中,系統(tǒng)在java.util包中,提供了一個(gè)字符串令StringTokenizer類(lèi),其主要作用是對(duì)字符串進(jìn)行信息分離。(1)構(gòu)造器方法publicStringTokenizer(String
str,String
delim)將字符串str按給定分隔符號(hào)delim進(jìn)行信息分離,構(gòu)成字符串令對(duì)象。(2)成員方法publicbooleanhasMoreTokens()如果字符串令還有元素,則返回真值。(3)成員方法publicStringnextToken()返回字符串令的下一個(gè)元素。(4)成員方法publicStringnextToken(String
delim)返回字符串令重新以按給定分隔符號(hào)delim進(jìn)行信息分離的下一個(gè)元素。多客戶信息廣播系統(tǒng)-信息分離1.字符串令StringToke多客戶信息廣播系統(tǒng)-用戶存儲(chǔ)在JDK1.4中,系統(tǒng)在java.util包中,提供了一個(gè)向量Vector類(lèi),其主要作用是可以存儲(chǔ)若干的元素(可以是任何類(lèi)型),并提供若干方法,以實(shí)現(xiàn)對(duì)這些元素的遍歷。(1)構(gòu)造器方法publicVector()構(gòu)造一個(gè)向量類(lèi)對(duì)象,其可以存儲(chǔ)任意多個(gè)元素(依據(jù)機(jī)器的內(nèi)存空間)。(2)成員方法publicintsize()返回向量類(lèi)對(duì)象中存儲(chǔ)的元素個(gè)數(shù)。(3)成員方法publicObjectelementAt(inti)返回向量類(lèi)對(duì)象中第i元素。(4)成員方法publicObjectfirstElement()返回向量類(lèi)對(duì)象中第1元素。(5)成員方法publicObjectlastElement()返回向量類(lèi)對(duì)象中最后1個(gè)元素。(6)成員方法publicvoidremoveElementAt(i)移除向量類(lèi)對(duì)象中第i元素。(7)成員方法publicvoidaddElement(Objectc)將c添加到向量類(lèi)對(duì)象。(8)成員方法publicStringtoString()將向量類(lèi)中的每個(gè)元素以字符串形式返回。多客戶信息廣播系統(tǒng)-用戶存儲(chǔ)在JDK1.4中,系統(tǒng)在java多客戶信息廣播系統(tǒng)-用戶顯示在JDK1.4中,系統(tǒng)在javax.swing包中,提供了一個(gè)下拉列表JList類(lèi),其主要作用是實(shí)現(xiàn)按條顯示信息,并能返回所選擇的信息內(nèi)容。(1)構(gòu)造器方法publicJList()構(gòu)造一個(gè)下拉列表類(lèi)對(duì)象,其可以存儲(chǔ)任意多個(gè)元素(依據(jù)機(jī)器的內(nèi)存空間)。(2)成員方法publicvoidsetListData(Vectorvs)將向量vs的每個(gè)元素作為下拉列表的顯示項(xiàng)。(3)成員方法publicObjectgetSelectedValue()返回被選擇的對(duì)象。多客戶信息廣播系統(tǒng)-用戶顯示在JDK1.4中,系統(tǒng)在java多客戶信息廣播系統(tǒng)-服務(wù)器端功能結(jié)構(gòu)
1.多線程機(jī)制在服務(wù)器端,由于需要建立多個(gè)用戶的連接,因此,需要有一個(gè)ConnectSocket線程,其主要工作流程如圖1所示:多客戶信息廣播系統(tǒng)-服務(wù)器端功能結(jié)構(gòu)1.多線程機(jī)制
服務(wù)器與客戶連接后,需要不斷進(jìn)行信息的收發(fā),因此,客戶與服務(wù)器進(jìn)行信息交互也需要用Client線程來(lái)實(shí)現(xiàn)。 在Client的構(gòu)造器中,主要實(shí)現(xiàn)客戶與服務(wù)器的連接通道(輸入流和輸出流),并分離客戶的信息,并將連接信息顯示在服務(wù)器端。
Client接下來(lái)的工作就是不停掃描套接字端口,對(duì)讀入的信息做相應(yīng)的處理。其主要工作流程如圖2所示:多客戶信息廣播系統(tǒng)-服務(wù)器端功能結(jié)構(gòu)
服務(wù)器與客戶連接后,需要不斷進(jìn)行信息的收發(fā),因此,客戶與服對(duì)服務(wù)器來(lái)說(shuō),必須將客戶信息保存,以實(shí)現(xiàn)服務(wù)器與每個(gè)客戶的信息交互。那么,對(duì)服務(wù)器來(lái)說(shuō),到底需要保存客戶的哪些信息呢?顯然,客戶名稱是需要保存的,此外,服務(wù)器與客戶的信息通道(輸入流和輸出流)也需要保存,這樣,才能實(shí)現(xiàn)服務(wù)器通過(guò)訪問(wèn)客戶列表,實(shí)現(xiàn)向每個(gè)客戶發(fā)送消息。因此,我們可以將服務(wù)器—客戶信息交互線程作為用戶列表信息保存起來(lái)。
客戶連接信息的存儲(chǔ)對(duì)服務(wù)器來(lái)說(shuō),必須將客戶信息保存,以實(shí)現(xiàn)服務(wù)器與每個(gè)客戶的信多客戶信息廣播系統(tǒng)-服務(wù)器-客戶連接線程classConnectSocketextendsThread{ Socketsocket; publicvoidrun(){ wh
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 印制中標(biāo)采購(gòu)合同范本
- 云倉(cāng)配送合同范本
- 勞動(dòng)關(guān)系有問(wèn)題合同范本
- 合同范本 渣場(chǎng)
- 制冷店設(shè)備維修合同范本
- 上街區(qū)合同范本
- 醫(yī)療垃圾回收合同范例
- 關(guān)于公司培訓(xùn)合同范例
- 收購(gòu)鴿子合同范本
- 代理公司勞務(wù)合同范本
- 《走近世界民間美術(shù)》 課件 2024-2025學(xué)年人美版(2024)初中美術(shù)七年級(jí)下冊(cè)
- 河北單招考試三類(lèi)職業(yè)適應(yīng)性測(cè)試考試題與答案
- 《大學(xué)英語(yǔ)教學(xué)大綱詞匯表》(1~4級(jí),5~6級(jí))
- 2022年在戲劇家協(xié)會(huì)會(huì)員大會(huì)上的講話
- DB11-T1630-2019城市綜合管廊工程施工及質(zhì)量驗(yàn)收規(guī)范
- 茂名市2008-2016年土地增值稅工程造價(jià)核定扣除標(biāo)準(zhǔn)
- 部編版語(yǔ)文九年級(jí)下冊(cè)《棗兒》公開(kāi)課一等獎(jiǎng)教案
- L阿拉伯糖與排毒課件
- 《現(xiàn)代交換原理》期末考試試習(xí)題和答案(免費(fèi))
- 手機(jī)開(kāi)發(fā)流程圖
- 隊(duì)列隊(duì)形比賽評(píng)分標(biāo)準(zhǔn)
評(píng)論
0/150
提交評(píng)論