我是一個(gè)新手,學(xué)習(xí)了Socket通信后,寒假花了20天寫了這個(gè)小項(xiàng)目,只有一個(gè)客戶端,而且也是一個(gè)尚未完工的客戶端,服務(wù)器端只用來接收,轉(zhuǎn)發(fā)或保存消息。本不準(zhǔn)備發(fā)出來的,因?yàn)轫?xiàng)目還在編寫當(dāng)中,實(shí)現(xiàn)的功能不多,且一些細(xì)節(jié)還沒有處理好,以后還會(huì)再寫一個(gè)比較細(xì)致的版本,不過老師要求了,就動(dòng)手寫了這篇總結(jié)。
?
項(xiàng)目名稱: 大山QQ , 用以紀(jì)念我的大三 。
?
項(xiàng)目意義 :對(duì)相關(guān)知識(shí)點(diǎn)的一個(gè)綜合練習(xí),熟悉Java通信方面的類的用法及組件的應(yīng)用,記錄我大三的學(xué)習(xí)痕跡。
?
通信協(xié)議 :字節(jié)流協(xié)議
?????????????
功能 :
1.注冊(cè)
2.查找
3.添加/刪除好友
4.添加/刪除分組
5.好友上下線提醒
6.發(fā)送在線離線消息
7.發(fā)送在線離線文件
?
界面 :全部采用空布局,所有組件都是通過setBounds(....)方法添加的
?
具體流程 :
?
服務(wù)器端
:
?????????? 服務(wù)器端還沒有怎么寫,只實(shí)現(xiàn)了基本的消息傳送功能。
??????????? 開啟服務(wù)器以后,首先讀取所有的用戶信息,等待客戶端的鏈接。由于尚未學(xué)習(xí)數(shù)據(jù)庫(kù),所有的用戶信息都是
以文件形式保存的。當(dāng)開啟服務(wù)器后,讀取的所有用戶信息都保存在輔助靜態(tài)類ChatTool的一個(gè)用戶Map<User_ID,User>中,當(dāng)客戶端連接上后,若為登錄消息且ID和password都正確,則將Client_Thread(服務(wù)器端的用戶通信線程類)添加至ChatTool類的線程Map<User_ID,Client_Thread>中,當(dāng)客戶端向流中寫入消息后,對(duì)應(yīng)服務(wù)器通信線程讀取該消息,并作出對(duì)應(yīng)操作。
?
客戶端
:
?
1.登錄
?賬號(hào)密碼框只能輸入10位以內(nèi)的數(shù)字0到9,實(shí)現(xiàn)方法有兩種 1.添加DocumentListener 2.添加keyListener
??????????????????????????????????? 具體見包MyComponent下的MyJTextField類
界面中的找回密碼,設(shè)置只是按鈕,還未添加功能。
?
若是賬號(hào)密碼均正確,服務(wù)器回發(fā)個(gè)人信息,包括賬號(hào),簽名,頭像,以及好友信息,未讀消息等,建立緩存,存儲(chǔ)好友的頭像,然后轉(zhuǎn)入好友列表界面。??
?
這一步有待改進(jìn),頭像的字節(jié)長(zhǎng)度遠(yuǎn)遠(yuǎn)大于其他信息的字節(jié)長(zhǎng)度,在本機(jī)建立好友頭像緩存,可以減少信息的傳輸,提高通信速度。?
?
?改進(jìn)方法:登錄前檢測(cè)本機(jī)好友頭像的個(gè)數(shù),傳送登錄信息時(shí)加上本機(jī)好友頭像的好友ID,服務(wù)器只回發(fā)其他好友的頭像以及更改了頭像的好友頭像即可。這一步更麻煩了,不過通信效率的提升很可觀。
?
?
2.注冊(cè)
?
做注冊(cè)界面時(shí),重要的就是在發(fā)送注冊(cè)消息前先檢測(cè)輸入的數(shù)據(jù)是否合法,并予以提示
?
?
當(dāng)所有的信息都無誤了,再向服務(wù)器發(fā)送消息。若注冊(cè)成功,服務(wù)器端保存用戶信息,我最開始是用一個(gè)文件保存的,
后來做其他功能時(shí)發(fā)現(xiàn)要修改用戶信息時(shí)會(huì)很麻煩,后改為每一項(xiàng)信息保存為一個(gè)文件。
注冊(cè)成功,回發(fā)消息,提示,返回登錄界面。
?
做注冊(cè)功能的時(shí)候,我意識(shí)到應(yīng)該要有容錯(cuò)處理,一切數(shù)據(jù)都合法的情況下再提交至服務(wù)器。
?
3.好友界面
界面上的所有圖標(biāo)都是JButton,setIcon(icon),沒有什么用處,主要是仿QQ,以后添加功能方便些
JTree顯示好友,頭像,賬號(hào),昵稱,是否在線,簽名
具體功能有5個(gè)
????? 1.添加/刪除分組?? 2.刪除好友?? 3.搜索用戶(search)? 4.雙擊好友頭像,彈出聊天界面
?
4.用戶查找界面
?
ID查找和昵稱查找等的實(shí)現(xiàn)方法是相同的,所以就只做了一個(gè)ID查找
服務(wù)器讀取要查找的用戶ID,若存在就回發(fā)該用戶ID,昵稱等模糊查詢回發(fā)的就是所有滿足搜索條件的用戶信息
?
當(dāng)點(diǎn)擊添加好友時(shí),服務(wù)器接收到消息后首先檢查被添加用戶是否在線,在線發(fā)送消息,不在線就在被請(qǐng)求用戶未讀消息目錄下的聊天消息下生成一個(gè)文件,寫入消息。當(dāng)被請(qǐng)求者用戶上線時(shí),服務(wù)器發(fā)送其信息時(shí)包含這些未讀消息,同時(shí)刪除未讀消息文件。
?
這是另一個(gè)我覺得很重要的地方----要保證信息的不丟失
?
比如A請(qǐng)求添加B為好友,首先A向服務(wù)器發(fā)送請(qǐng)求消息,為保證B收到請(qǐng)求,?若B不在線,則將請(qǐng)求保存到B的未讀文件中,在其上線時(shí)讀取自身信息時(shí)(服務(wù)器在發(fā)送完溫度消息后刪除該消息),在通知B,若B在線則直接向其發(fā)送消息。B接收請(qǐng)求,選擇分組,刷新界面,同時(shí)向服務(wù)器發(fā)送消息,服務(wù)器在保存信息,同時(shí)通知A結(jié)果,A在選擇分組,刷新界面,再將結(jié)果發(fā)到服務(wù)器保存。
?
就是將客戶端的一切改動(dòng)都發(fā)到服務(wù)器保存下來。做修改個(gè)人信息的功能的時(shí)候,比如修改昵稱,簽名,密碼等也是一樣的
過程。
5.好友上下線提醒
?
我覺得這個(gè)功能的實(shí)現(xiàn)是這個(gè)項(xiàng)目最有價(jià)值的地方。采用了觀察者模式。
?? 具體做法如下:
?? 自定義一個(gè)接口MsgListener,含有方法ReceiveMsgAction(Msg msg);
自定義一個(gè)接口subject,含有方法addMsgListener(MsgListener l),removeMsgListener(MsgListener l),
??? fireMsgListener(Msg msg);
??? 客戶端的通信線程類ClientThread繼承Subject
????定義類MyJTree_AsListeber extends JTree implements MsgListener ,重載ReceiveMsgAction(Msg msg),創(chuàng)建對(duì)象時(shí),將之注冊(cè)到對(duì)應(yīng)的通信線程上。當(dāng)對(duì)應(yīng)通信線程類對(duì)象調(diào)用fireMsgListener(Msg msg)時(shí),通知JTree對(duì)象作出相應(yīng)顯示刷新。
?
??? 之前我一直都很追求外觀,可當(dāng)老師第一次講到設(shè)計(jì)模式的時(shí)候,我才意識(shí)到純粹的最求外觀是沒什么意義的,最重要的還是程序的結(jié)構(gòu),一個(gè)好的軟件的設(shè)計(jì)應(yīng)該是多種結(jié)構(gòu)的綜合,結(jié)構(gòu)的好壞決定了程序的拓展性和可維護(hù)性。至于技術(shù)點(diǎn),最好是能讀懂源碼,理解原理,這需要經(jīng)驗(yàn),現(xiàn)在的我還差得遠(yuǎn),對(duì)于技術(shù)只停留在用的階段,還未上升到理論。
?
?
6.聊天界面
?
?視頻語音截圖震動(dòng)功能都沒實(shí)現(xiàn)
可以修改字體屬性,傳送消息,文件。未保存消息
?
?
?
?
震動(dòng)的具體原理就是setLocation(x,y)方法的運(yùn)用
截圖,遠(yuǎn)程就是Robot類的應(yīng)用
視頻功能需要JMF的相關(guān)知識(shí),還沒有研究?
?
7.傳送文件
?
?流程如下:1.在線文件的傳送????? 先發(fā)送請(qǐng)求,對(duì)方同意后,開啟一個(gè)服務(wù)器(有堵塞,應(yīng)該放在線程中),回發(fā)給發(fā)送者,然后發(fā)送者連上該服務(wù)器,開啟多個(gè)線程(我開啟的是2個(gè)線程),分段傳送文件,具體實(shí)現(xiàn)是RandomAccessFile類。
如DataImputStream類對(duì)象只能從文件的第一個(gè)字節(jié)開始讀,但RandomAccessFile類對(duì)象可以隨機(jī)讀取文件,調(diào)用seek(x),或者skipBytes(X)方法,改變指針位置,就可以實(shí)現(xiàn)隨機(jī)讀取某一位置的字節(jié)。迅雷下載就是這種原理。開始,不清楚seek(x),或者skipBytes(X)方法是如何改變文件指針的,是讀取X個(gè)字節(jié)再丟掉,還是直接改變指針在內(nèi)存中的地址呢?經(jīng)過測(cè)試,答案是后者。?? 2.離線文件的傳送???? 由于只有一個(gè)通信I/o,傳送文件應(yīng)該另外創(chuàng)建Socket對(duì)象連上服務(wù)器,發(fā)送完文件后再關(guān)閉Socket。
?
?
?
?
?項(xiàng)目的不足 :
1.數(shù)據(jù)的存儲(chǔ)??? 文件存儲(chǔ)終究不如數(shù)據(jù)庫(kù)存儲(chǔ),讀取速度慢,性能低。只適合小群體的聊天
2.結(jié)構(gòu)???? 雖然嘗試使用了觀察者模式,但客戶端程序的耦合度還是比較高的,一個(gè)好的結(jié)構(gòu)應(yīng)該是多種設(shè)計(jì)模式的綜合
3.功能???? 功能比較少,而且有缺陷,比如還沒有加上遠(yuǎn)程,視頻等功能,前幾天已經(jīng)把遠(yuǎn)程寫好了,不過對(duì)圖像的壓縮度
????????????? 感到不滿意,其他功能的細(xì)節(jié)也有待改進(jìn),比如在添加好友時(shí),我沒有先判斷是否請(qǐng)求對(duì)象已是自身好友等,都
????????????? 是些細(xì)節(jié)的地方,還有修改個(gè)人信息的功能等等,這是都不難,但這些細(xì)節(jié)都決定著項(xiàng)目的友好性。很重要。
4.有一個(gè)問題沒有解決,好友查找界面,表格刷新時(shí)會(huì)包空指針的錯(cuò),沒找到具體原因。
5.代碼的結(jié)構(gòu)不是很好,注解寫的少了
6.沒有創(chuàng)新?????? 純粹是技術(shù)的練習(xí),嘗試使用了一個(gè)設(shè)計(jì)模式,沒有創(chuàng)新,沒什么價(jià)值
?
收獲 :
1.意識(shí)到結(jié)構(gòu)和友好的重要性
2.在調(diào)試的過程中,第一次意識(shí)到Java程序?qū)ο到y(tǒng)內(nèi)存,CPU的占用問題,意識(shí)到了一些小問題,比如讀寫文件不關(guān)流的話,就不會(huì)釋放內(nèi)存。
3.讓我的心情很平靜,不再浮躁
?
注:項(xiàng)目中的所有圖片都是截圖截下來的,在壓縮包的圖片文件夾中。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
