




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、嵌入式課程設(shè)計(論文)androidl聊天室設(shè)計學(xué) 生: 學(xué) 號:指導(dǎo)教師:李季 老師專 業(yè):計算機(jī)科學(xué)與技術(shù)重慶大學(xué)計算機(jī)學(xué)院二o一一年十二月摘 要此系統(tǒng)設(shè)計了一個基于android系統(tǒng)與pc之間的通信,采用socket流式套接字進(jìn)行網(wǎng)絡(luò)通信。其中android系統(tǒng)的模擬器作為客戶端,客戶端采用獲取手機(jī)號碼作為該客戶端的唯一標(biāo)識,pc作為服務(wù)器端。其中客戶端的設(shè)計過程中主要用chatclientactivity 文件實現(xiàn)客戶端的各個widget的功能以及利用socket向服務(wù)器端發(fā)送和接受服務(wù)器端的消息。服務(wù)器端主要用serverthread 服務(wù)器線程初始化serversocket并將對客
2、戶端監(jiān)聽到得socket封裝到clientthread線程中并將該線程存放到vector數(shù)組用于服務(wù)器與指定客戶端交互,以及啟動broadcast線程和clientthread線程,以及將,其中clientthread線程主要用于將監(jiān)聽到客戶端發(fā)送的消息存放到消息隊列并將其保存在sql2000數(shù)據(jù)庫中以及根據(jù)分類顯示在控制臺上,broadcast線程主要獲取消息隊列中的消息并根據(jù)消息的性質(zhì)確定是否將此消息廣播到所有在線客戶端或是發(fā)送到某些指定的客戶端。startserver主要用于啟動serverthread線程,即啟動整個服務(wù)器。dodatabase主要用于連接數(shù)據(jù)庫和實現(xiàn)對數(shù)據(jù)庫的添加操作
3、。最后此系統(tǒng)實現(xiàn)了群聊與私聊的功能,并能夠?qū)⒘奶煊涗浄诸惐4娴綌?shù)據(jù)庫中。關(guān)鍵詞:android,socket通信,線程同步,tcp/ip協(xié)議目 錄中文摘要1 tcp/ip及socket簡介1 1.1 tcp/ip協(xié)議簡介1 1.2 socket套接字簡介12 系統(tǒng)總體架構(gòu)23 系統(tǒng)功能實現(xiàn)33.1 數(shù)據(jù)交互格式33.2 服務(wù)器功能實現(xiàn)4 3.2.1 startserver類4 3.2.2 serverthread類5 3.2.3 clientthread類6 3.2.4 broadcast類8 3.2.1dodatabase類103.3 客戶端功能實現(xiàn)113.4 系統(tǒng)功能展示153.4.1客戶
4、端功能展示153.4.2服務(wù)器端及數(shù)據(jù)庫展示16 4 系統(tǒng)存在的問題及改進(jìn)方法17 4.1 系統(tǒng)存在的問題174.2 系統(tǒng)改進(jìn)方法174 自我評價18參考文獻(xiàn)191 tcp/ip及socket簡介 1.1 tcp/ip協(xié)議簡介tcp/ip是transm control protocol/internet protocol 的簡寫,又稱網(wǎng)絡(luò)通信協(xié)議,是internet最基本的協(xié)議。tcp/ip協(xié)議是“可靠的”、“面相連接”的網(wǎng)絡(luò)傳輸協(xié)議。tcp/ip協(xié)議遵循的是一個抽象的分層模型,這個模型中所有的tcp/ip系列網(wǎng)絡(luò)協(xié)議都被歸納到四個抽象的“層”中。每一抽象層建立在低一層提供的服務(wù)上,并為高一層
5、服務(wù)。tcp/ip參考模型從上到下分別包括網(wǎng)絡(luò)接口層、網(wǎng)絡(luò)互連層、傳輸層和應(yīng)用層四層。1.2 socket套接字簡介在網(wǎng)絡(luò)上的兩個程序通過一個雙向的通信鏈路實現(xiàn)數(shù)據(jù)交換,這個雙向鏈路的一段就被稱為一個socket,socket通常用來實現(xiàn)客戶端和服務(wù)器端的鏈接。socket是tcp/ip協(xié)議的一個十分流行的編程界面,一個socket有一個ip地址和一個端口號確定。在java環(huán)境中實現(xiàn)基于tcp/ip協(xié)議的網(wǎng)絡(luò)編程都需要采用socket機(jī)制。并且與基于url的網(wǎng)絡(luò)編程socket編程提供更高的傳輸效率。socket通常采用c/s結(jié)構(gòu),使用socket進(jìn)行c/s程序設(shè)計的一般鏈接過程如下圖:圖1.
6、1 socket編程連接一般過程2 系統(tǒng)總體架構(gòu)整個系統(tǒng)由客戶端和服務(wù)器端組成,其中客戶端位于android模擬器上,服務(wù)器端位于pc上??蛻舳藙?chuàng)建的socket與服務(wù)端的serversocket進(jìn)行交互來實現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)交互。其中socket與serversocket交互過程如下:(1) 服務(wù)器端程序創(chuàng)建一個serversocket,然后調(diào)用accept()方法等待客戶連接(2) 客戶端創(chuàng)建一個socket并請求與服務(wù)器端程序建立連接。(3) 服務(wù)器端程序接受客戶端的連接請求,并創(chuàng)建一個新的socket與該客戶端建立專線連接。(4) 建立了連接的客戶端及服務(wù)器端的兩個socket在一個有服務(wù)器端
7、程序創(chuàng)建的單獨(dú)線程上對話,對話方式采用getinputstream()、getoutputstream()得到的輸入與輸出流進(jìn)行數(shù)據(jù)的讀取與輸出??蛻舳说膕ocket與服務(wù)器端的serversocket的通信如下圖:圖2.1 socket與serversocket通信圖(5) 服務(wù)器端開始等待新的連接請求,重復(fù)(2)(5)的過程。在客戶端程序?qū)崿F(xiàn)了界面的顯示以及與服務(wù)器端的數(shù)據(jù)交互。在服務(wù)器端程序一共包含五個類,其名稱及功能如下表所示:startserver啟動服務(wù)器主線程serverthread,即啟動服務(wù)器serverthread服務(wù)器監(jiān)聽端口線程,負(fù)責(zé)創(chuàng)建serversocket以及監(jiān)聽
8、是否有新客戶端連接,并記錄客戶端連接以及需要發(fā)送的消息clientthread維持服務(wù)器與單個客戶端的連接線程,負(fù)責(zé)接受客戶端發(fā)送來的消息broadcast服務(wù)器向客戶端發(fā)送廣播線程,負(fù)責(zé)向客戶端發(fā)送消息dodatabase連接數(shù)據(jù)庫,將消息拆解后按類型存放到數(shù)據(jù)庫chatdemo的messages表中表2.1 服務(wù)器端程序的四個類功能實現(xiàn)通信功能的流程圖如下:圖2.2 系統(tǒng)通信功能流程圖3 系統(tǒng)功能實現(xiàn)3.1數(shù)據(jù)交互格式對于此聊天系統(tǒng),主要存在如下三類數(shù)據(jù):1、登陸2、傳遞消息3、退出這三類數(shù)據(jù)都是需要向服務(wù)器端發(fā)送的數(shù)據(jù),因為了在服務(wù)器端處理的數(shù)據(jù)不被混淆,必須對他們的數(shù)據(jù)格式進(jìn)行規(guī)格化,
9、此系統(tǒng)的數(shù)據(jù)規(guī)格如下圖:表3.1 消息格式圖消息種類: “l(fā)”登陸;“s”傳遞消息;“c”退出,目的地址: 要發(fā)往特定客戶端的手機(jī)號標(biāo) 識: 用來標(biāo)識不同種類的信息符號其中“$”發(fā)送的消息標(biāo)識;“#”客戶上下線標(biāo)識。源 地 址: 消息來源的客戶端手機(jī)號碼時 間: 獲取到的發(fā)送消息時的時間內(nèi) 容: 如果登陸則為“上線了”,如果退出則為“下線了”,如果是傳遞消息則為想發(fā)送的內(nèi)容;其中對于登陸和退出消息,送往服務(wù)器端進(jìn)行拆分后將其目標(biāo)地址置空,對于傳遞消息,如果目標(biāo)地址和源地址相同則表示將該消息發(fā)送給所有的客戶端,反之,則只是發(fā)送到這兩個地址的客戶端中。3.2服務(wù)器端功能實現(xiàn)3.2.1 starts
10、erver類startserver線程是整個服務(wù)器的主線程,當(dāng)執(zhí)行這個工程文件時執(zhí)行這個類中的main函數(shù),在main函數(shù)中創(chuàng)建了一個實例化了一個serverthread線程命名為serverthread,并啟動該線程,代碼如下:public class startserver private static serverthread serverthread;public static void main(string args) / todo auto-generated method stubserverthread = new serverthread();serverthread.st
11、art();3.2.2 serverthread類該類在構(gòu)造函數(shù)中實例化了兩個vector數(shù)組,分別用于存放clientthread線程和存放從客戶端發(fā)送來的消息,并命名為clients 和messages。此外還對serversocket進(jìn)行了初始化,然后啟動broadcast方法。代碼如下:public vector clients;public vector messages;public serverthread()clients = new vector();messages= new vector();try serversocket = new serversocket(port
12、); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();try myipaddress = inetaddress.getlocalhost(); catch (unknownhostexception e) / todo auto-generated catch blocke.printstacktrace();broadcast = new broadcast(this);broadcast.start();構(gòu)造方法執(zhí)行后,接著執(zhí)行該線程的run()方法。在run()函數(shù)中用了一個死循環(huán)實現(xiàn)
13、不停的對客戶端的連接進(jìn)行監(jiān)聽,一旦監(jiān)聽到客戶端的連接請求,就獲得該客戶端的socket并將其封裝在clientthread線程中,然后啟動clientthread線程并將該線程壓入clients數(shù)組中以實現(xiàn)服務(wù)器與指定客戶端或所有客服端發(fā)送數(shù)據(jù)。此外由于clients屬于臨界資源,同一時刻只能允許被一個線程操作,因此使用了線程同步方法synchronized(clients)。代碼如下:public void run()while(true)try socket socket = serversocket.accept();system.out.println(socket.getinetad
14、dress().gethostaddress();clientthread clientthread = new clientthread(socket,this);clientthread.start();if(socket!=null)synchronized(clients)clients.addelement(clientthread); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();3.2.3 clientthread類當(dāng)serverthread線程開啟了clientthread線
15、程后,通過構(gòu)造函數(shù)獲得了客戶端的socket套接字,然后通過socket的getinputstream()方法和getoutputstream()方法獲取輸入輸出流。public clientthread(socket socket,serverthread serverthread)this.clientsocket = socket;this.serverthread = serverthread;try in = new datainputstream(clientsocket.getinputstream();out = new dataoutputstream(clientsocke
16、t.getoutputstream(); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();然后執(zhí)行run()方法監(jiān)聽socket是否有新的消息,然后根據(jù)消息的類別相應(yīng)處理后在控制臺上顯示出來,并把message的第14到25的子串(username)作為clientthread的唯一標(biāo)識id,此標(biāo)識可以用來實現(xiàn)從一個客戶端向另一指定客戶端發(fā)送數(shù)據(jù)。并利用domsg()方法將message拆分后存放到數(shù)據(jù)庫中,同時將message壓入到messages消息隊列中。代碼如下:public void
17、 run()while(true)try string message = in.readutf();synchronized(serverthread.messages)if(message !=null)domsg(message);id = message.substring(14, 25);serverthread.messages.addelement(message);if(message.subsequence(0, 1).equals(s)if(message.substring(1,12).equals(message.substring(14,25)system.out.p
18、rintln(message.substring(1,12) + message.substring(24);elsesystem.out.println($+message.substring(14,25)+ 對 +message.substring(1,12)+message.substring(25);elsesystem.out.println(message.substring(12); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();break;private void domsg
19、(string message) / todo auto-generated method stubcatgory = message.substring(0,1);orgid = message.substring(14,25);time = message.substring(26,34);if(catgory.equals(s)goalid = message.substring(1,12);content =message.substring(36);elsegoalid = ;content =message.substring(34);try dodb.addmsg(time, c
20、atgory, orgid, goalid, content); catch (exception e) / todo auto-generated catch blocke.printstacktrace();3.2.4 broadcast類通過serverthread線程調(diào)用該類后,serverthread類通過broadcast構(gòu)造函數(shù)傳給serverthread實例,然后執(zhí)行該線程的run()方法,沒循環(huán)一次線程休眠200ms,然后取出messages中尚未發(fā)送出的消息,將消息按其格式拆分后根據(jù)其意圖送往各個客戶端或是指定客戶端,是實現(xiàn)群聊個私聊的功能。同樣,消息數(shù)組是臨界資源,所以,
21、用到了synchronized(serverthread.messages)方法,判斷該消息為下線功能,則將根據(jù)id刪除vector中的clientthread線程。源代碼如下:public void run()while(true)try thread.sleep(200); catch (interruptedexception e) / todo auto-generated catch blocke.printstacktrace();synchronized(serverthread.messages)if(serverthread.messages.isempty()continu
22、e;/獲取消息隊列隊首消息str = (string)this.serverthread.messages.firstelement();synchronized(serverthread.clients)system.out.println(serverthread.clients.size();for(int i=0;iserverthread.clients.size();i+)/獲取該客戶端線程clientthread =(clientthread)serverthread.clients.elementat(i);try clientthread.out.writeutf(str);
23、 catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();/從消息隊列中刪除該消息this.serverthread.messages.remove(str);3.2.5 dodatabase類該類有兩個方法addmsg()和getconnection()方法,其中g(shù)etconnection()方法用于獲取數(shù)據(jù)庫chatdemo的連接句柄。addmsg()方法用于對chatdemo中的表messages進(jìn)行寫操作。實現(xiàn)代碼如下:public class dodatabase public void a
24、ddmsg(string time, string catgory, string orgid, string goalid, string content)throws exception /打開連接connection conn = getconnection();/ 執(zhí)行操作preparedstatement pst = conn.preparestatement(insert into messages values(?,?,?,?,?);pst.setstring(1, time); /時間pst.setstring(2, catgory);/消息種類pst.setstring(3,
25、 orgid);/源地址pst.setstring(4, goalid);/目的地址pst.setstring(5, content);/內(nèi)容pst.execute();/ 關(guān)閉數(shù)據(jù)庫conn.close();private connection getconnection() throws classnotfoundexception,sqlexception class.forname(net.sourceforge.jtds.jdbc.driver);connection conn = drivermanager.getconnection(jdbc:jtds:sqlserver:/lo
26、calhost:1433/chatdemo, sa, );return conn;3.3客戶端功能實現(xiàn)圖3.1 客戶端界面其源代碼如下:public class chatclientactivity extends activity implements runnableprivate edittext usernameedit,ipedit,historyedit,messageedit;private button loginbutton,leavebutton,sendbutton;private string username ,ip,chat_txt,chat_in;public s
27、tatic final int port = 8521;/端口號public datainputstream in=null;public dataoutputstream out=null;public socket socket;public thread thread;public boolean flag = false; /標(biāo)識是否登陸,true為已登錄,false為未登錄 override public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); setcontentvie
28、w(r.layout.main); usernameedit = (edittext)findviewbyid(r.id.username); ipedit = (edittext)findviewbyid(r.id.ip); historyedit = (edittext)findviewbyid(r.id.history); messageedit = (edittext)findviewbyid(r.id.message); loginbutton = (button)findviewbyid(r.id.loginbutton); leavebutton = (button)findvi
29、ewbyid(r.id.leave); sendbutton = (button)findviewbyid(r.id.sendbutton); loginbutton.setonclicklistener(listener); leavebutton.setonclicklistener(listener); sendbutton.setonclicklistener(listener); view.onclicklistener listener = new view.onclicklistener() overridepublic void onclick(view v) / todo a
30、uto-generated method stubswitch(v.getid()case r.id.loginbutton:/登陸if(flag=true)toast.maketext(chatclientactivity.this, 已經(jīng)登陸過了, 3000).show();return;username = usernameedit.gettext().tostring();ip = ipedit.gettext().tostring();if(username!= & username!=null & ip != null)/目的地址和源地址不能為空;try socket = new
31、socket(ip,port); /實例化socket/獲取輸入輸出流in = new datainputstream(socket.getinputstream();out = new dataoutputstream(socket.getoutputstream();date now = new date(system.currenttimemillis(); /獲取系統(tǒng)時間simpledateformat format = new simpledateformat(hh:mm:ss);string nowstr = format.format(now);out.writeutf($+us
32、ername+ +nowstr+上線了); catch (unknownhostexception e) / todo auto-generated catch blocke.printstacktrace(); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();thread = new thread(chatclientactivity.this);thread.start();flag = true;break;case r.id.sendbutton: /發(fā)送消息if(flag = fal
33、se)toast.maketext(chatclientactivity.this, 沒有登陸,請登陸, 3000).show();return;chat_txt = messageedit.gettext().tostring();if(chat_txt !=null)date now = new date(system.currenttimemillis(); /獲取當(dāng)前時間simpledateformat format = new simpledateformat(hh:mm:ss);string nowstr = format.format(now);try out.writeutf(
34、_+username+ +nowstr+說n+chat_txt); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();elsetry out.writeutf(請說話); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();break;case r.id.leave: /退出if(flag = false)toast.maketext(chatclientactivity.this, 沒有登陸,請登
35、陸, 3000).show();return;try out.writeutf(#+username+下線了!);out.close();in.close();socket.close(); catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();flag = false;toast.maketext(chatclientactivity.this, 已經(jīng)退出!, 3000).show();break;overridepublic void run() /服務(wù)端反饋的消息/ todo auto-gen
36、erated method stubwhile(true)try chat_in = in.readutf();chat_in +=n;mhandler.sendmessage(mhandler.obtainmessage(); /發(fā)到主線程的消息隊列中 catch (ioexception e) / todo auto-generated catch blocke.printstacktrace();handler mhandler = new handler()public void handlemessage(message msg)historyedit.append(chat_in)
37、; /在historyedit文本框中追加消息super.handlemessage(msg);3.4系統(tǒng)功能展示3.2.1 客戶端功能展示圖3.2 客戶端5554發(fā)送接收消息界面 圖3.3 客戶端5556發(fā)送接收消息界面圖3.4 客戶端5558發(fā)送接收消息界面3.2.1 服務(wù)器端及數(shù)據(jù)庫展示圖3.5 服務(wù)器控制臺顯示 圖3.6 數(shù)據(jù)庫存儲顯式4 系統(tǒng)存在問題及改進(jìn)方法4.1系統(tǒng)存在的問題此系統(tǒng)實現(xiàn)了android系統(tǒng)聊天室的群聊和私聊功能以及實現(xiàn)了在服務(wù)器端將接收到的消息存儲到,但是由于時間限制此系統(tǒng)基本實現(xiàn)了android系統(tǒng)的聊天室的實現(xiàn)群發(fā)功能,但是由于時間較緊,還有一些沒有實現(xiàn)的功能。首先在安全性上考慮不周,登陸時只需要輸入用戶名就能夠進(jìn)入系統(tǒng),而且沒有檢測多個模擬器上是否有同名的情況。其次,對很多可能出現(xiàn)異常的情況沒有處理。再次,設(shè)計上還不夠嚴(yán)謹(jǐn),在客戶端與服務(wù)器端進(jìn)行數(shù)據(jù)通信時有很多數(shù)據(jù)交互,此系統(tǒng)只實現(xiàn)了在客戶端對發(fā)送的消息進(jìn)行了記錄,但只實現(xiàn)了數(shù)據(jù)庫的寫操作。在客戶端本地沒有實現(xiàn)數(shù)據(jù)存儲機(jī)制以便日后需要,比如:用戶名,密碼等。最后,android客戶端界面設(shè)計不足,比如:當(dāng)歷史記錄edittext中存放了太多內(nèi)容時需要設(shè)置清除功能。4.2系統(tǒng)改
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 結(jié)構(gòu)基礎(chǔ)知識培訓(xùn)
- 紀(jì)法知識培訓(xùn)課件制作app
- 省考公務(wù)員評價試題及答案研究
- 二零二五離婚房產(chǎn)贈與協(xié)議書范例
- 墳拆遷協(xié)議書
- 2024年檔案管理員職業(yè)發(fā)展規(guī)劃試題及答案
- 農(nóng)業(yè)技術(shù)服務(wù)協(xié)議合同書范例二零二五年
- 大氣簡約設(shè)計風(fēng)-投資亮點(diǎn)匯報
- 二零二五房屋拆遷補(bǔ)償協(xié)議書范文
- 二零二五香港股權(quán)轉(zhuǎn)讓協(xié)議書
- 中國肝病診療管理規(guī)范
- 2024年江蘇省泰州市保安員理論考試題庫及答案(完整)
- 專題01《水銀花開的夜晚》 高考語文二輪復(fù)習(xí)
- 送達(dá)地址確認(rèn)書(訴訟類范本)
- 2023版北京協(xié)和醫(yī)院重癥醫(yī)學(xué)科診療常規(guī)
- 計算機(jī)輔助設(shè)計(Protel平臺)繪圖員級試卷1
- 除法口訣表(完整高清打印版)
- 河北省城市建設(shè)用地性質(zhì)和容積率調(diào)整管理規(guī)定---精品資料
- 講課實錄-洛書時間數(shù)字分析法
- 施工質(zhì)量月報(樣板)
- (完整版)員工入職檔案表
評論
0/150
提交評論