




已閱讀5頁(yè),還剩26頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
. 編號(hào): 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)題 目: 基于UDP的聊天程序 系 別: 計(jì)算機(jī)科學(xué)與工程學(xué)院 摘要隨著網(wǎng)絡(luò)技術(shù)的發(fā)展及人們生活的需求,網(wǎng)絡(luò)聊天已越來(lái)越受到人們的青睞 。網(wǎng)絡(luò)聊天已經(jīng)成為人們工作生活中傳遞信息、交流感情的重要工具,給人們帶來(lái)了很大的方便。 本課題是開(kāi)發(fā)一個(gè)基于UDP的局域網(wǎng)聊天系統(tǒng),運(yùn)用軟件工程的設(shè)計(jì)流程,綜合運(yùn)用數(shù)據(jù)庫(kù)編程技術(shù)、Windows程序設(shè)計(jì)技術(shù)、網(wǎng)絡(luò)通訊技術(shù),此網(wǎng)絡(luò)聊天工具采用客戶端/服務(wù)器(C/S)模式,客戶端采用UDP與服務(wù)器連接,客戶端與客戶端之間通過(guò)UDP互相通訊。服務(wù)器端具有服務(wù)器端口設(shè)置,此聊天工具能實(shí)現(xiàn)多人聊天功能,適用于局域網(wǎng)使用的網(wǎng)絡(luò)聊天工具,其操作簡(jiǎn)單,靈活性好,運(yùn)行也比較穩(wěn)定。 關(guān)鍵詞:網(wǎng)絡(luò)通訊;客戶端/服務(wù)器模型;用戶數(shù)據(jù)報(bào)協(xié)議;套接字;.一、需求分析1.1 課程設(shè)計(jì)目的 開(kāi)發(fā)一個(gè)專用于實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)之間即時(shí)通訊的軟件以方便兩臺(tái)計(jì)算機(jī)之間信息的交流。在連接并通信時(shí)尤其是近程的即時(shí)通訊徹底的脫離了遠(yuǎn)程的服務(wù)器避免了和遠(yuǎn)程服務(wù)器連接時(shí)過(guò)多的浪費(fèi)網(wǎng)絡(luò)資源。并且避免了服務(wù)器忙或與服務(wù)器無(wú)法連接時(shí)浪費(fèi)過(guò)多時(shí)間用于和服務(wù)器建立連接因此這個(gè)軟件是極具適應(yīng)性和實(shí)用性的即時(shí)通訊軟件本次課程設(shè)計(jì)的目的是學(xué)習(xí)基于UDP協(xié)議實(shí)現(xiàn)網(wǎng)絡(luò)聊天程序已達(dá)到學(xué)會(huì)面向無(wú)連接方式的程序設(shè)計(jì)方法并理解網(wǎng)絡(luò)編程中面向無(wú)連接的概念。 1.2 課程設(shè)計(jì)的內(nèi)容 用戶數(shù)據(jù)報(bào)UDP是一個(gè)無(wú)連接協(xié)議使用這種協(xié)議時(shí)并不需要在兩臺(tái)計(jì)算機(jī)之間建立固定的連接也就是說(shuō)通信雙方?jīng)]有服務(wù)器和客戶機(jī)之分它們之間進(jìn)行的是對(duì)等通信所以它的優(yōu)勢(shì)很明顯是現(xiàn)代通信不可或缺的一部分。所以利用它的優(yōu)勢(shì)設(shè)計(jì)一個(gè)可以聊天的軟件實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)間的即時(shí)通訊。 1.3 課程設(shè)計(jì)要求 基于UDP協(xié)議實(shí)現(xiàn)的聊天和一對(duì)多的聊天提供友好的用戶界面便于用戶進(jìn)行操作。 二 . UDP協(xié)議的理解:UDP協(xié)議是英文UserDatagramProtocol的縮寫,即用戶數(shù)據(jù)報(bào)協(xié)議,主要用來(lái)支持那些需要在計(jì)算機(jī)之間傳輸數(shù)據(jù)的網(wǎng)絡(luò)應(yīng)用。包括網(wǎng)絡(luò)視頻會(huì)議系統(tǒng)在內(nèi)的眾多的客戶/服務(wù)器模式的網(wǎng)絡(luò)應(yīng)用都需要使用UDP協(xié)議。UDP協(xié)議從問(wèn)世至今已經(jīng)被使用了很多年,雖然其最初的光彩已經(jīng)被一些類似協(xié)議所掩蓋,但是即使是在今天,UDP仍然不失為一項(xiàng)非常實(shí)用和可行的網(wǎng)絡(luò)傳輸層協(xié)議。UDP協(xié)議直接位于IP(網(wǎng)際協(xié)議)協(xié)議的頂層。UDP協(xié)議的主要作用是將網(wǎng)絡(luò)數(shù)據(jù)流量壓縮成數(shù)據(jù)報(bào)的形式。一個(gè)典型的數(shù)據(jù)報(bào)就是一個(gè)二進(jìn)制數(shù)據(jù)的傳輸單位。每一個(gè)數(shù)據(jù)報(bào)的前8個(gè)字節(jié)用來(lái)包含報(bào)頭信息,剩余字節(jié)則用來(lái)包含具體的傳輸數(shù)據(jù)。UDP協(xié)議使用端口號(hào)為不同的應(yīng)用保留其各自的數(shù)據(jù)傳輸通道。正是采用這一機(jī)制實(shí)現(xiàn)對(duì)同一時(shí)刻內(nèi)多項(xiàng)應(yīng)用同時(shí)發(fā)送和接收數(shù)據(jù)的支持。數(shù)據(jù)發(fā)送一方(可以是客戶端或服務(wù)器端)將UDP數(shù)據(jù)報(bào)通過(guò)源端口發(fā)送出去,而數(shù)據(jù)接收一方則通過(guò)目標(biāo)端口接收數(shù)據(jù)。有的網(wǎng)絡(luò)應(yīng)用只能使用預(yù)先為其預(yù)留或注冊(cè)的靜態(tài)端口;而另外一些網(wǎng)絡(luò)應(yīng)用則可以使用未被注冊(cè)的動(dòng)態(tài)端口。因?yàn)閁DP報(bào)頭使用兩個(gè)字節(jié)存放端口號(hào),所以端口號(hào)的有效范圍是從0到65535。一般來(lái)說(shuō),大于49151的端口號(hào)都代表動(dòng)態(tài)端口。數(shù)據(jù)報(bào)的長(zhǎng)度是指包括報(bào)頭和數(shù)據(jù)部分在內(nèi)的總的字節(jié)數(shù)。因?yàn)閳?bào)頭的長(zhǎng)度是固定的,所以該域主要被用來(lái)計(jì)算可變長(zhǎng)度的數(shù)據(jù)部分(又稱為數(shù)據(jù)負(fù)載)。數(shù)據(jù)報(bào)的最大長(zhǎng)度根據(jù)操作環(huán)境的不同而各異。從理論上說(shuō),包含報(bào)頭在內(nèi)的數(shù)據(jù)報(bào)的最大長(zhǎng)度為65535字節(jié)。不過(guò),一些實(shí)際應(yīng)用往往會(huì)限制數(shù)據(jù)報(bào)的大小,有時(shí)會(huì)降低到8192字節(jié)。UDP協(xié)議使用報(bào)頭中的校驗(yàn)值來(lái)保證數(shù)據(jù)的安全。校驗(yàn)值首先在數(shù)據(jù)發(fā)送方通過(guò)特殊的算法計(jì)算得出,在傳遞到接收方之后,還需要再重新計(jì)算。如果某個(gè)數(shù)據(jù)報(bào)在傳輸過(guò)程中被第三方篡改或者由于線路噪音等原因受到損壞,發(fā)送和接收方的校驗(yàn)計(jì)算值將不會(huì)相符,由此UDP協(xié)議可以檢測(cè)是否出錯(cuò)。UDP協(xié)議并不提供數(shù)據(jù)傳送的保證機(jī)制。如果在從發(fā)送方到接收方的傳遞過(guò)程中出現(xiàn)數(shù)據(jù)報(bào)的丟失,協(xié)議本身并不能做出任何檢測(cè)或提示,由于排除了信息可靠傳遞機(jī)制,將安全和排序等功能移交給上層應(yīng)用來(lái)完成,極大降低了執(zhí)行時(shí)間,使速度得到了保證。三. UDP協(xié)議特點(diǎn) 1、UDP傳送數(shù)據(jù)前并不與對(duì)方建立連接,即UDP是無(wú)連接的,在傳輸數(shù)據(jù)前,發(fā)送方和接收方相互交換信息使雙方同步。 2、UDP不對(duì)收到的數(shù)據(jù)進(jìn)行排序,在UDP報(bào)文的首部中并沒(méi)有關(guān)于數(shù)據(jù)順序的信息(如TCP所采用的序號(hào)),而且報(bào)文不一定按順序到達(dá)的,所以接收端無(wú)從排起。 3、UDP對(duì)接收到的數(shù)據(jù)報(bào)不發(fā)送確認(rèn)信號(hào),發(fā)送端不知道數(shù)據(jù)是否被正確接收,也不會(huì)重發(fā)數(shù)據(jù)。 4、UDP傳送數(shù)據(jù)較TCP快速,系統(tǒng)開(kāi)銷也少。 5、由于缺乏擁塞控制(congestion control),需要基于網(wǎng)絡(luò)的機(jī)制來(lái)減小因失控和高速UDP流量負(fù)荷而導(dǎo)致的擁塞崩潰效應(yīng)。換句話說(shuō),因?yàn)閁DP發(fā)送者不能夠檢測(cè)擁塞,所以像使用包隊(duì)列和丟棄技術(shù)的路由器這樣的網(wǎng)絡(luò)基本設(shè)備往往就成為降低UDP過(guò)大通信量的有效工具。數(shù)據(jù)報(bào)擁塞控制協(xié)議(DCCP)設(shè)計(jì)成通過(guò)在諸如流媒體類型的高速率UDP流中增加主機(jī)擁塞控制來(lái)減小這個(gè)潛在的問(wèn)題。 從以上特點(diǎn)可知,UDP提供的是無(wú)連接的、不可靠的數(shù)據(jù)傳送方式,是一種盡力而為的數(shù)據(jù)交付服務(wù)。四. 基于C/S的多客服端相互通信原理分析:在C/S模式中,它是在分散式 ,集中式,以及分布式基礎(chǔ)上發(fā)展起來(lái)的一種新模型,目前大多數(shù)網(wǎng)絡(luò)通信以及應(yīng)用都屬于這種模型,C/S模式將一個(gè)網(wǎng)絡(luò)事務(wù)分為兩部分,一部分是客戶端(Client),他為用戶提供網(wǎng)絡(luò)請(qǐng)求服務(wù)的接口,另一部分是服務(wù)端(Server),它負(fù)責(zé)接受用戶對(duì)服務(wù)的請(qǐng)求,并將這些服務(wù)透明的提供給用戶,既適用于實(shí)際應(yīng)用的程序,又實(shí)用于真正的計(jì)算裝置,舉例來(lái)說(shuō),我們到飯店吃飯時(shí),要首先提出請(qǐng)求吃什么,屬于客戶端,飯店服務(wù)員根據(jù)請(qǐng)求提供相應(yīng)的服務(wù),屬于服務(wù)端,至于相應(yīng)的飯菜是由哪一個(gè)廚師來(lái)做,則由飯店的服務(wù)員去聯(lián)系,而客戶端只需要和服務(wù)器打交道就行了,從程序?qū)崿F(xiàn)上來(lái)說(shuō),客戶端和服務(wù)器打交道實(shí)際上是兩個(gè)進(jìn)程打交道,服務(wù)端啟動(dòng)server進(jìn)程,并等待客戶端與其聯(lián)系,而客戶端則啟動(dòng)客戶進(jìn)程和服務(wù)器打交道。當(dāng)服務(wù)器進(jìn)程處理完一個(gè)客服進(jìn)程請(qǐng)求的信息之后,由接著等待其他客戶的請(qǐng)求。五 套接字編程原理分析:圖1.1 套接字編程原理圖注釋:socket(),使用前創(chuàng)建一個(gè)新的套接字;bind(),將套接字地址與所創(chuàng)建的套接字號(hào)聯(lián)系起來(lái);send()與recv(),數(shù)據(jù)的發(fā)送與接收;closesocket(),關(guān)閉套接字。六、概要設(shè)計(jì)服務(wù)器客戶機(jī)甲客戶機(jī)乙客戶機(jī)丙圖2.1 整體框架設(shè)計(jì)圖服務(wù)器端主要實(shí)現(xiàn)的功能是啟動(dòng)一個(gè)監(jiān)聽(tīng)的進(jìn)程,開(kāi)放自己的端口號(hào)為7777,不斷的監(jiān)聽(tīng)是否有新的客服端進(jìn)程向自己發(fā)送連接請(qǐng)求,為每一個(gè)主動(dòng)連接自己的客戶端設(shè)置一個(gè)ID號(hào)設(shè)置一個(gè)threads的容器用來(lái)管理客戶端的線程。與客戶端建立連接,實(shí)現(xiàn)socket通信,對(duì)于服務(wù)器端是先接受數(shù)據(jù)流然后再發(fā)送數(shù)據(jù)流,客服端發(fā)送過(guò)來(lái)的信息經(jīng)服務(wù)器端然后轉(zhuǎn)發(fā)到其他所有的客戶端,服務(wù)器端相當(dāng)于中間的橋梁??蛻舳艘笾饕獙?shí)現(xiàn)的功能是建立一個(gè)圖形的界面,用于顯示聊天信息等,并且建立與服務(wù)器端的通信,主動(dòng)的向服務(wù)器端發(fā)送連接請(qǐng)求,然后對(duì)輸入文本框注冊(cè)事件監(jiān)聽(tīng)并且發(fā)送給客服端,不斷的監(jiān)聽(tīng)服務(wù)器端發(fā)來(lái)的信息,然后顯示出來(lái)。七、詳細(xì)設(shè)計(jì)服務(wù)器端:創(chuàng)建服務(wù)端接口建立一個(gè)seversocket的類svsocket創(chuàng)建一個(gè)容器用來(lái)管理客戶端進(jìn)程開(kāi)始監(jiān)聽(tīng),監(jiān)聽(tīng)是否有客戶端連接,有的話與其建立連接分配ID監(jiān)聽(tīng)線程監(jiān)聽(tīng)端口是否有消息傳入如果有的話接收信息再將信息發(fā)送到其他的所有的客服端當(dāng)某客戶離開(kāi),結(jié)束他與其他人的通信為客戶端連接創(chuàng)建線程從容器vector中刪除該線程表示該線程已經(jīng)離開(kāi)聊天室,結(jié)束兩者之間連接圖7.1 服務(wù)器端整體設(shè)計(jì)流程圖客戶端建立一個(gè)seversocket的類,并且創(chuàng)建一個(gè)vector用來(lái)管理客戶端的線程,然后就開(kāi)始檢測(cè),如果有客戶端請(qǐng)求與服務(wù)器連接就與其建立socket連接,創(chuàng)建進(jìn)程設(shè)置ID,告訴其他的客戶端有新的客戶端接入,然后開(kāi)始監(jiān)聽(tīng)所有的客戶端線程如果有信息通過(guò)端口進(jìn)入就接受然后再發(fā)送給其他客戶端,如果有客戶端退出,就會(huì)告訴其他的客戶端并且關(guān)閉與該客戶端的socket連接,然后在vector里面刪除相應(yīng)的線程。主界面服務(wù)器界面,當(dāng)運(yùn)行服務(wù)器端則出現(xiàn)運(yùn)行客服端登錄心得體會(huì):經(jīng)過(guò)兩個(gè)星期的學(xué)習(xí)和實(shí)踐,我也算是順利的完成了計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì),同時(shí)對(duì)計(jì)算機(jī)網(wǎng)絡(luò)有一個(gè)大致的了解,在實(shí)踐過(guò)程中遇到了很多的困難,感覺(jué)自己很難將理論與實(shí)踐相結(jié)合,覺(jué)得我們學(xué)習(xí)的那些知識(shí)也派不上用場(chǎng),通過(guò)這次課設(shè),我深刻的認(rèn)識(shí)到實(shí)踐與理論必須 要想結(jié)合才能使所學(xué)的知識(shí)變成可用的,通過(guò)自己的努力和老師同學(xué)們的幫助,多了一種看待問(wèn)題的角度;我也發(fā)現(xiàn)了我所學(xué)知識(shí)不扎實(shí),只是走馬觀花的應(yīng)付考試,在以后的學(xué)習(xí)中需要時(shí)刻的告誡自己,踏踏實(shí)實(shí)做好每一步。本次課程設(shè)計(jì)是利用java語(yǔ)言編寫的,雖說(shuō)自己以前接觸過(guò)這種語(yǔ)言,但是經(jīng)過(guò)這兩周的學(xué)習(xí),我受益匪淺。首先,我進(jìn)一步弄懂了JAVA語(yǔ)言的編程方法和原則,并學(xué)會(huì)了編寫java程序。其次,使我更深層次的理解到JAVA語(yǔ)言是一種面向?qū)ο蟮恼Z(yǔ)言,具有可視化編程的特點(diǎn)且代碼具有可移植等特點(diǎn)。本次課程設(shè)計(jì)是實(shí)現(xiàn)一個(gè)UDP即時(shí)通訊程序。經(jīng)過(guò)編寫程序和運(yùn)行,調(diào)試程序,我對(duì)java語(yǔ)言有了更深的了解。另外,使我對(duì)UDP協(xié)議的特點(diǎn)和工作過(guò)程有了更深的了解。UDP協(xié)議提供無(wú)連接的、不可靠的服務(wù)。它工作于傳輸層,是傳輸層的重要協(xié)議之一。最后,UDP協(xié)議是利用客戶端和服務(wù)器端模型來(lái)實(shí)現(xiàn)傳輸?shù)摹?本次課程設(shè)計(jì)使我明白了知識(shí)的重要性,同時(shí)也更加懂得實(shí)踐更不可少。我們要經(jīng)常把所學(xué)的知識(shí)運(yùn)用到實(shí)踐,這樣,才能充分的融會(huì)貫通。同時(shí),也使我認(rèn)識(shí)到自己動(dòng)手能力太差,為我以后的學(xué)習(xí)和發(fā)展提供了一個(gè)警鐘!本次課程設(shè)計(jì)的過(guò)程中,雖然遇到了不少問(wèn)題,但最后還是成功的完成了。這次課設(shè)對(duì)于我而言是有很大的收獲,懂得獨(dú)立尋找資料學(xué)習(xí),這是最大的收獲,在以后的工作中肯定會(huì)面臨不懂得問(wèn)題,有了這次課設(shè)的經(jīng)驗(yàn),就能夠去獨(dú)立學(xué)習(xí)并解決困難。主要代碼package server; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import .ServerSocket; import .Socket; import java.util.ArrayList; import java.util.Date; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class server extends JFrame private JTextArea allmsg; private JTextField currnum,totalnum,copyright,chatmsg; private JButton send; private JScrollPane js; int num1,num2,port;/* - num1:當(dāng)前在線人數(shù) num2:總上線人數(shù) port:服務(wù)端口號(hào) -*/ private ServerSocket ss; ArrayList lists;/存放所有在線用戶 public server() super(聊天室服務(wù)器端); this.setSize(310,660); this.setLocation(200,50); lists = new ArrayList(); num1 = num2 =0; port = 7777; currnum = new JTextField( 當(dāng)前在線人數(shù): +num1); currnum.setEnabled(false); totalnum = new JTextField( 上線總?cè)藬?shù): +num2); totalnum.setEnabled(false); allmsg = new JTextArea(); allmsg.append( - 系統(tǒng)消息 -n); allmsg.setEditable(false); allmsg.setLineWrap(true); /允許自動(dòng)換行 js = new JScrollPane(allmsg);/為JTextArea添加滾動(dòng)條 chatmsg = new JTextField(在此輸入系統(tǒng)信息); chatmsg.addActionListener(new ActionListener() public void actionPerformed(ActionEvent arg0) String str = chatmsg.getText().trim(); if(!.equals(str) sendmsg(new Date().toLocaleString()+ - 系統(tǒng)消息: +str);chatmsg.setText(); else JOptionPane.showMessageDialog(null, 消息不能為空,錯(cuò)誤,JOptionPane.OK_OPTION); chatmsg.setText();/* - 發(fā)送信息后,將輸入欄中的信息清空 - */ ); send = new JButton(發(fā)送); send.addActionListener(new ActionListener() public void actionPerformed(ActionEvent arg0) String str = chatmsg.getText().trim(); if(!.equals(str) sendmsg(new Date().toLocaleString()+ - 系統(tǒng)消息: +str);chatmsg.setText(); else JOptionPane.showMessageDialog(null, 消息不能為空,錯(cuò)誤,JOptionPane.OK_OPTION); chatmsg.setText();/* - 發(fā)送信息后,將輸入欄中的信息清空 - */ ); addcomponettocontainer(); this.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent we) sendmsg(SYSTEM_CLOSED);/* - 向客戶端發(fā)送服務(wù)器關(guān)閉信息 - */ destory(); ); start(); /* - 啟動(dòng)連接服務(wù) - */ public void addcomponettocontainer() Container c = this.getContentPane(); c.setLayout(null); currnum.setBounds(20,15,130,20); totalnum.setBounds(155,15,125,20); js.setBounds(10,50,280,500); chatmsg.setBounds(10,560,180,30); send.setBounds(220,560,70,30); copyright.setBounds(10,600,280,20); c.add(currnum); c.add(totalnum); c.add(js); c.add(chatmsg); c.add(send); c.add(copyright); this.setVisible(true); this.setResizable(false); public void start() boolean isStarted = false;/* - 用于標(biāo)記服務(wù)器是否已經(jīng)正常啟動(dòng) - */ try this.ss = new ServerSocket(port); isStarted = true; this.allmsg.append(new Date().toLocaleString()+ 服務(wù)器啟動(dòng) 端口: +port+n); while(isStarted) Socket client = this.ss.accept(); /* - 監(jiān)聽(tīng)客戶端的連接 - */ DataInputStream in = new DataInputStream(client.getInputStream(); String name = in.readUTF(); user u = new user(); = name; u.socket = client; lists.add(u); /將該用戶加到列表中去 num1+; num2+; currnum.setText( 當(dāng)前在線人數(shù): +num1); totalnum.setText( 上線總?cè)藬?shù): +num2); this.allmsg.append(new Date().toLocaleString()+ : ++ 登錄 n); new Thread(new ClientThread(u).start();/* - 為該用戶啟動(dòng)一個(gè)通信線程 - */ catch (IOException e) System.out.println(服務(wù)器已經(jīng)啟動(dòng).); System.exit(0); class ClientThread implements Runnable user user = null; boolean isConnected = true; DataInputStream dis = null; DataOutputStream dos = null; public ClientThread(user u) this.user = u; try this.dis = new DataInputStream(this.user.socket.getInputStream(); this.dos = new DataOutputStream(this.user.socket.getOutputStream(); catch (IOException e) / TODO Auto-generated catch block e.printStackTrace(); public void run() readmsg(); /* - 讀取客戶的聊天信息 - */ public void readmsg() while(isConnected) try String msg = dis.readUTF(); if(quit&logout.equals(msg)/當(dāng)用戶關(guān)閉客戶端窗口時(shí),發(fā)送quit字符串 表示用戶已經(jīng)退出 num1-; try this.dis.close(); this.dos.close(); this.user.socket.close(); this.isConnected = false; catch(IOException ioe) ioe.printStackTrace(); finally this.isConnected = false; if(dis!=null) this.dis.close(); if(dos!=null) this.dos.close(); if(this.user.socket!=null) this.user.socket.close(); lists.remove(this.user);/從列表中刪除該用戶 currnum.setText( 當(dāng)前在線人數(shù): +num1); allmsg.append(new Date().toLocaleString()+ : ++ 退出n); else sendmsg(msg); catch (IOException e) e.printStackTrace(); /* - 將信息進(jìn)行轉(zhuǎn)發(fā) - */ public void sendmsg(String msg) user us = new user(); DataOutputStream os = null; if(lists.size()0) for(int i=0;ilists.size();i+) us = (user)lists.get(i); try os = new DataOutputStream(us.socket.getOutputStream(); os.writeUTF(msg); catch (IOException e) e.printStackTrace(); else JOptionPane.showMessageDialog(null, 當(dāng)前無(wú)用戶在線。發(fā)送消息失敗,失敗,JOptionPane.OK_OPTION); public void destory() try this.ss.close(); catch (IOException e) / TODO Auto-generated catch block e.printStackTrace(); this.dispose(); public static void main(String args) new server(); package client; import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.io.*; import .*; public class client extends JFrame private JTextField name; private JTextField ip; private JButton ok,cancle; public Socket socket; public client() super(登錄框); this.setSize(400,80); this.setLocation(100,100); name = new JTextField(昵稱); ip = new JTextField(); ok = new JButton(登錄); cancle = new JButton(取消); ok.addActionListener(new listenEvent(); cancle.addActionListener(new listenEvent(); addcomponettocontainer(); this.setDefaultCloseOperation(EXIT_ON_CLOSE); public void addcomponettocontainer() Container c = this.getContentPane(); c.setLayout(null); name.setBounds(10,10,100,30); ip.setBounds(120,10,100,30); ok.setBounds(230,10,70,30); cancle.setBounds(310,10,70,30); c.add(name); c.add(ip); c.add(ok); c.add(cancle); this.setVisible(true); this.setResizable(false); public class listenEvent implements ActionListener public void actionPerformed(ActionEvent event) / TODO Auto-generated method stub if(event.getSource()=ok) String n = name.getText().trim(); String i = ip.getText().trim(); if(.equals(n)|.equals(i) JOptionPane.showMessageDialog(null,昵稱、IP不能夠?yàn)榭?,錯(cuò)誤,JOptionPane.OK_OPTION); elselogin(n,i); if(event.getSource()=cancle) name.setText(); ip.setText(); public void login(String name,String ip) try socket = new Socket(ip,7777); DataOutputStream out = new DataOutputStream(socket.getOutputStream(); out.writeUTF(name); out.flush();/強(qiáng)制輸出緩存中的內(nèi)容 /out.close(); new ClientFrame(name,socket); destroywindow(); catch (UnknownHostException e) JOptionPane.showMessageDialog(null,找不到主機(jī)地址(IP錯(cuò)誤/網(wǎng)絡(luò)故障)!,錯(cuò)誤,JOptionPane.OK_OPTION); catch (IOException e) public void destroywindow() this.dispose(); public static void main(String args) new client(); package server;import .*; public class user String name; Socket socket; package client; import java.awt.Color; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .Socket; import java.util.Date; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class ClientFrame extends JFrame private JTextArea allmsg; private JTextField welcome,copyright,chatmsg; private JButton send; private JScrollPane js; private boolean isConnected = true; public DataOutputStream out; public DataInputStream in; public Socket s = null; String nic; /* - 保存用戶昵稱 -*/ /* * 初始化客戶端資源 * 1.獲取從LoginFrame傳遞過(guò)來(lái)的參數(shù) * 2.初始化界面元素 * 3.初始化通信所需要的資源 EG:輸入/輸出流(DataInputStream/DataOutputStream) * */ public ClientFrame(String name,Socket socket) this.setSize(310,660); this.setLocation(290,50); this.setTitle(聊天室客戶端);/* - 指定窗口的標(biāo)題 -*/ this.s = socket;/* - 接收從LoginFrame中傳遞過(guò)來(lái)的Socket -*/ this.nic = name+ 說(shuō): ; welcome = new JTextField( 歡迎您來(lái)到聊天室 ,100); welcome.setBackground(Color.blue); welcome.setEnabled(false); copyright = new JTextField( - all copyright TOP-king -); copyright.setEnabled(false); allmsg = new JTextArea(); allmsg.setEditable(false); allmsg.append( 系統(tǒng)消息: 歡迎登錄在線聊天室 n); js = new JScrollPane(allmsg);/為JTextArea添加滾動(dòng)條 chatmsg = new JTextField(在此輸入聊天信息); chatmsg.addActionListener(new listen(); send = new JButton(發(fā)送); send.addActionListener(new listen();/* - 添加事件監(jiān)聽(tīng)器 -*/ try out = new DataOutputStream(s.getOutputStream(); in = new DataInputStream(s.getInputStream(); catch (IOException e) JOptionPane.showMessageDialog(null, 系統(tǒng)異常,錯(cuò)誤,JOptionPane.OK_CANCEL_OPTION); addcomponettocontainer(); /* - 當(dāng)用戶關(guān)閉窗口時(shí)進(jìn)行相關(guān)的處理 eg:Socket Data(Input/Output)Stream 的關(guān)閉-*/ this.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent we) sendmsg(quit&logout);/* - 向服務(wù)器端發(fā)送關(guān)閉信息 -*/ isConnected = false; destory();/* - 銷毀窗口資源 -*/ ); new Thread(new linread().start();/* - 啟動(dòng)讀取信息線程 -*/ public void addcomponettocontainer() Container c = this.getContentPane(); c.setLayout(
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 供電公司外委管理辦法
- 虛擬展覽技術(shù)-洞察及研究
- DeepSeek與區(qū)塊鏈技術(shù)推動(dòng)大灣區(qū)港群一體化發(fā)展
- 智慧教室材料管理辦法
- 養(yǎng)蜂管理辦法(試行)
- 村級(jí)資金使用管理辦法
- 公司內(nèi)部招待管理辦法
- 農(nóng)村便利設(shè)施管理辦法
- 探究《水滸傳》精彩章節(jié)
- 使用軟件考勤管理辦法
- 毀林毀草違規(guī)行為集中整治實(shí)施方案
- 日本2025年食品過(guò)敏原培訓(xùn)
- 中新天津生態(tài)城教育系統(tǒng)招聘教職人員筆試真題2024
- GB/T 45817-2025消費(fèi)品質(zhì)量分級(jí)陶瓷磚
- DB37∕T 5302-2024 既有城市橋梁現(xiàn)場(chǎng)檢測(cè)及承載能力評(píng)估技術(shù)標(biāo)準(zhǔn)
- 安徽省池州市貴池區(qū)2024-2025學(xué)年八年級(jí)下學(xué)期數(shù)學(xué)期末檢測(cè)試卷(含答案)
- 正畸接診標(biāo)準(zhǔn)化流程
- 中心靜脈壓(CVP)監(jiān)測(cè)與護(hù)理
- 酒店前臺(tái)接待禮儀與溝通技巧練習(xí)題
- 床上用品采購(gòu) 投標(biāo)方案
- 口腔工藝管理課件
評(píng)論
0/150
提交評(píng)論