版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、課程編號:B080109003網(wǎng)絡(luò)應(yīng)用程序設(shè)計實踐報告姓名學(xué)號班級軟件150 1指導(dǎo)教師血 回 回 費園園實踐課程名稱網(wǎng)絡(luò)應(yīng)用程序設(shè)計實踐開設(shè)學(xué)期2 0 1 6- 2 0 1 7 第二學(xué)期開設(shè)時間第1周第3周報告日期2 0 1 7. 0 3. 1 7評定成績評定人簽字評定日期東北大學(xué)軟件學(xué)院1.實踐目的L 寫出本次實踐的目的,要求簡潔清楚。(1)理解ftp通信原理;(2)學(xué)習使用Socket和多線程編寫簡單的FTP服務(wù)器;(3)學(xué)習使用Sokcet編寫簡單的FTP客戶端;(4)理解HTTP通信原理;(5)學(xué)習使用Socket編寫HTTP服務(wù)器;(6)學(xué)習使用Socket編寫HTTP客戶端;(7
2、)理解WebSocket的通信原理;(8)使用tomcat服務(wù)器搭建多人聊天室;2.預(yù)習內(nèi)容L 寫出本次實踐過程中你所用到的知識;(1)FTP通信流程和通信命令FTP使用2個端口,一個數(shù)據(jù)端口和一個命令端口(也叫做控制端口)。這兩個端口一般 是21(命令端口)和20(數(shù)據(jù)端口)。(2)Socket 編程利用TCP協(xié)議進行通信的兩個應(yīng)用程序,server和client交互過程:1)服務(wù)器創(chuàng)建一個ServerSocket,然后調(diào)用accept方法等待客戶連接2)客戶端程序創(chuàng)建一個socket并請求與服務(wù)器建立連接3)在連接的socket上進行單獨的線程對話4)服務(wù)器開始等待新的連接請求(多線程)(
3、3)多線程編程為了保證FTP服務(wù)器能夠同時處理多個客戶端的請求,服務(wù)器為每個客戶端分配一個線 程。(4)HTTP通信原理http的請求格式HTTP請求格式BtanH hireEntity bo4yiak Thiinri: HI IffL BtanH hireEntity bo4yiak Thiinri: HI IffL hll|TFr* tnniiWULkXhttp的應(yīng)答模式HTTP應(yīng)答格式WebSocket 概念在WebSocket API,瀏覽器和服務(wù)器只需要做一個握手的動作,然后,瀏覽器和服務(wù) 器之間就形成了一條快速通道。兩者之間就直接可以數(shù)據(jù)互相傳送。在此 WebSocket 協(xié)議中,
4、為我們實現(xiàn)即時服務(wù)帶來了兩大好處:Header互相溝通的Header是很小的-大概只有2 BytesServer Push服務(wù)器的推送,服務(wù)器不再被動的接收到瀏覽器的request之后才返回數(shù)據(jù),而是 在有新數(shù)據(jù)時就主動推送給瀏覽器。WebSocket通信規(guī)則1)客戶端發(fā)起請求,服務(wù)器端創(chuàng)建一個ChatAnnotation對象,自動運行start方法, 將 Websocket會話對象session作為入?yún)?。服?wù)器端將當前ChatAnnotation對象加入 到static的集合中。2)客戶端onopen方法自動運行。3)客戶端通過事件觸發(fā)socket.send()方法,服務(wù)器端incoming
5、方法自動運行,客 戶端發(fā)送的信息自動作為方法入?yún)?,服?wù)器端可以遍歷static的集合,把消息推送給所 有的客戶端。4)收到推送消息后,客戶端的onmessage方法自動運行。5)客戶端如果推出,客戶端的onclose方法自動運行,接著服務(wù)器端的end方法 自動運行,在end方法中,從static的集合中刪除當前ChatAnnotation對象。3.實踐內(nèi)容和實踐過程1.編寫簡單的FTP客戶端程序;編寫簡單的FTP服務(wù)器程序?qū)嵺`內(nèi)容本實驗要求完成以下功能(使用PASV模式):優(yōu)先級功能名稱功能說明優(yōu)先級獲取文件列 表給定用戶工作目錄,獲得文件列表,包括文件名稱,文件大小,文件創(chuàng)建 時間獲取文件列
6、 表 TOC o 1-5 h z 上傳文件到用戶指定工作目錄中高文件上傳上傳文件夾到用戶指定工作目錄中低支持斷點續(xù)傳低文件下載給定用戶工作目錄文件下載給定用戶工作目錄,下載文件給定用戶工作目錄,下載文件夾支持斷點續(xù)傳實現(xiàn)過程1)服務(wù)器創(chuàng)建一個ServerSocket,然后調(diào)用accept方法等待客戶連接2)客戶端程序創(chuàng)建一個socket并請求與服務(wù)器建立連接3)在連接的socket上進行單獨的線程對話客戶端通過發(fā)送命令來使服務(wù)器做出相應(yīng)的反應(yīng)。當發(fā)送PASV命令時候,服務(wù)器進入被動模式,并打開數(shù)據(jù)端口。客戶端連接數(shù)據(jù)端 口,兩者之間即可以通過命令端口處理請求,數(shù)據(jù)端口傳輸數(shù)據(jù),比如文件(夾)的
7、上傳、 下載。上傳:將文件寫進DataOutputStream輸出流之中,流中的數(shù)據(jù)通過數(shù)據(jù)端口傳輸至服 務(wù)器。服務(wù)器端同樣從數(shù)據(jù)端口獲取流DataInputStream,并將其輸出為文件。此間需要傳 輸文件的名字、大小等等參數(shù)。文件夾的上傳與下載:類似于單文件操作。首先遍歷文件夾,獲取文件的fileList集合,發(fā)送文件夾名字,在 另一端新建同名文件夾。循環(huán)發(fā)送所有文件,發(fā)送一個文件之后,另一端開始下載,下載 完畢返回驗證。開始發(fā)送第二個文件,繼續(xù)下載,直至所有文件傳輸完畢。操作過程如流 程圖:4)服務(wù)器開始等待新的連接請求(多線程) 下圖為項目流程:FA5V開放數(shù)據(jù)端口FA5V開放數(shù)據(jù)端口
8、關(guān)鍵技術(shù)開啟被動模式:if (s.equals(PASV)/ 如果是被動模式 if (pasvSocket != null) pasvSocket.close();try pasvSocket = new ServerSocket(0);int pPort = pasvSocket.getLocalPort();if (pPort 1024) pPort = 1025;response(227 entering passive mode ( +InetAddress. getLocalHost ().getHostAddress().replace(, .) + , + pPort + );D
9、ataOutputStream dataOutputStream=newDataOutputStream(socket.getOutputStream();dataOutputStream.writeUTF(InetAddress. getLocalHost().getHostAddress();dataOutputStream.flush();dataOutputStream.writeInt(pPort);dataOutputStream.flush();if (pasvSocket != null) dataSocket = pasvSocket.accept();/ 阻塞 respon
10、se (數(shù)據(jù)端口連接成功,繼續(xù)輸入命令:); catch (Exception e) / TODO Auto-generated catch blockif (pasvSocket != null) pasvSocket.close(); pasvSocket = null;return;獲取文件list:if (s.equals(LIST) File file = new File(this. currentDir);/ 路徑名字File files = file.listFiles();String list =”;for (int i = 0; i files. length; i+)
11、long time = filesi.lastModified(); String stime = new SimpleDateFormat(yyyy-MM-dd hh:mm:ss).format(new Date(time);list += filesi.getName() + “t + filesi.length() + kb + t + stime + n;DataOutputStream dataOutputStream2 = newDataOutputStream(dataSocket.getOutputStream();dataOutputStream2.writeUTF(list
12、);response(150來自數(shù)據(jù)端口的文件list:);return;文件夾的傳輸:if (response_code.equals(153) / RETR DataInputStream dis = newDataInputStream(dataSocket.getInputStream();String dirName = dis.readUTF();/ 獲取文件夾名字 System. out.println(文件夾的名字:+ dirName); File file = new File(clientDir + / + dirName); file.mkdir();5int fileN
13、um = dis.readInt();/ 獲取文件的數(shù)量System. out.println(文件的數(shù)量:+ fileNum);for (int i = 0; i 開始下載文件:“+ fileName + ”, 文件大小為:+ fileLength + B );while (true) int read = 0;read = dis.read(sendBytes);if (read = -1) break;transLen += read;fos.write(sendBytes, 0, read);fos.flush();if (transLen = (int) fileLength) br
14、eak;System. out.println(下載文件:“+ fileName + 成 功 );DataOutputStream dataOutputStream3 = new DataOutputStream(dataSocket.getOutputStream();dataOutputStream3.writeUTF(done);dataOutputStream3.flush();System. out.println(文件夾+ dirName + 下載成功”);遇到的問題及解決方案在處理文件夾傳輸?shù)臅r候,遇到了一些問題:上傳多個文件,但是在服務(wù)器端僅僅收到一個文件,而且文件的大小是所有
15、的文件的總 和。后來經(jīng)過分析,發(fā)現(xiàn)是由于上傳的時候使用的流操作,將所有文件順序通過一個流操作 進行傳輸,服務(wù)器端接收文件的時候會把流中的數(shù)據(jù)解析成文件,但是并不會把多個文件解 析出來,最終導(dǎo)致所有的數(shù)據(jù)堆在一個文件之中。解決方案:在流程圖中也可以看到文件夾的傳輸方式,現(xiàn)對客戶端上傳文件夾至服務(wù)器來進行說 明??蛻舳双@取文件夾下在所有File對象,存為一個集合。同時可以得到文件的數(shù)量等等基本屬性,客戶端將這些信息發(fā)送至服務(wù)器,服務(wù)器按照指令創(chuàng)建文件夾。接著客戶端發(fā)送 第一個文件,而后暫停(readline()方法阻塞進程)。服務(wù)器開始接收第一個文件,接收完畢 發(fā)送一道指令給客戶端,readlin
16、e()方法執(zhí)行之后,進入下個循環(huán)發(fā)送第二個文件。直至所有 文件循環(huán)結(jié)束。上傳文件夾完畢。2.編寫簡單的HTTP 1.1客戶端程序;編寫簡單的HTTP 1.1服務(wù)器程序;(1)實踐內(nèi)容功能名稱功能說明優(yōu)先級服務(wù)器功能提供HTML,JPG等MIME類型的資源高客戶端功能訪問服務(wù)器,獲取HTML和JPG資源,保存到本地磁盤高訪問服務(wù)器,獲取WMV等其他資源類型,保存到本地磁盤低(2) 實現(xiàn)過程返回返回JPG請求 W返回返回JPG請求 W、返回 |返I可reA 請產(chǎn) I噸開超”_1返回請求自灣求JPG請求U*啃求灣求JPG請求U*啃求HIXL(3)關(guān)鍵技術(shù)X斷開遙(3)關(guān)鍵技術(shù)連接socket端口:S
17、ocket socket=new Socket(localhost”, 8081);客戶端發(fā)送HTTP請求:PrintWriter writer=new PrintWriter(socket.getOutputStream();DataOutputStream dataOutputStream=newDataOutputStream(socket.getOutputStream();String fileName=final_travel/index.html”;發(fā)送請求頭GET方式中,請求數(shù)據(jù)掛在URL后,POST方式中,請求數(shù)據(jù)放在請 求體中writer.println(GET +file
18、Name+“ HTTP/1.1);writer.println(Host:localhost);writer.println(connection:keep-alive);亞丘6小511口();空行writer.flush();客戶端接收服務(wù)器返回的資源:InputStream inputStream=socket.getInputStream();BufferedReader reader=new BufferedReader(newInputStreamReader(inputStream);String firstLineOfResponse=reader.readLine();/HTT
19、P/1.1 200 OKSystem. out.println(firstLineOfResponse);String secondLineOfResponse=reader.readLine();/Content-Type:image/jpgSystem. out.println(secondLineOfResponse);String thirdLineOfResponse = reader.readLine();/Content-Length:System. out.println(thirdLineOfResponse);String fourthLineOfResponse = re
20、ader.readLine();/空行byte b = new byte 1024;String realFileName=fileName;if (fileName.contains(/)/處理 類似于文件夾/文件.后綴 類型的文件String口 num=fileName.split(/);realFileName=numnum. length-11;FileOutputStream out = newFileOutputStream(/home/scc/eclipse/workspaces/experient_2/client+/+realFileName );String string=
21、out.toString();System. out.println(string);int len=inputStream.read(b);while (len!=-1) out.write(b, 0, len);len = inputStream.read(b);inputStream.close();out.close();(4)遇到的問題及解決方案問題:客戶端與服務(wù)器進行通訊時候,使用流操作來傳輸數(shù)據(jù),出現(xiàn)返回文件偶爾出錯的現(xiàn)象。 解決方案:每次客戶端接收完數(shù)據(jù)之后,都將HTTP連接斷開,需要時候再進行連接。3. 編寫Websocket聊天室功能,包括客戶端JavaScript和服務(wù)器
22、端Servlet(1)實踐內(nèi)容本實驗要求完成以下功能:功能名稱功能說明優(yōu)先級完成度多人聊天在網(wǎng)頁上實現(xiàn)多人聊天高多人聊天跟某個人聊 天用戶登錄,顯示在線列表,指定和某個人聊天中用戶登錄,顯示在線列 表,指定和某個人聊天在線客服在線客服功能低未完成實現(xiàn)過程客戶端與服務(wù)器建立連接并進行第一條通訊的流程圖:群發(fā)消息的通訊流程:顯示在線列表的實現(xiàn)流程:私聊功能,以文字形式描述如下:用戶1發(fā)送消息,格式為+&用戶2昵稱。服務(wù)端識別之后,將用戶1的私聊對象talkTo 屬性設(shè)置為用戶2, isPrivateChat屬性設(shè)置為true。根據(jù)提供的用戶名,獲取到用戶2的 chatAnontation,并將用戶
23、2的私聊對象talkTo屬性設(shè)置為用戶1 ,isPrivateChat屬性設(shè)置為true。因此可以實現(xiàn):當進入私聊模式后,用戶1或者用戶2發(fā)送一條消息,在后臺判斷 isPrivateChat,如果為true,那么將根據(jù)該用戶的talkTo屬性存儲的用戶名獲取到私聊對象的 session,只將消息廣播給特定私聊對象。當退出私聊模式時候,一方輸入-&即可,后臺清除用戶1和用戶2的talkTo屬性,并將 isPrivateChat均設(shè)置為false。從而結(jié)束私聊模式,今后發(fā)送消息均為群聊消息,廣播給所有的在 線用戶。關(guān)鍵技術(shù)顯示在線列表的實現(xiàn):當用戶連接或者斷開時,均會執(zhí)行以下方法(核心代碼):首先
24、將所有的用戶信息獲取到,封裝成一個JSON對象,將JSON格式的字符串廣播出去 JSONObject jsonObject_send=new JSONObject();JSONArray jsonArray_send=new JSONArray();for (User user2 : users) jsonArray_send.put(user2.getName();try jsonObject_send.put(list”, jsonArray_send); catch (JSONException e) e.printStackTrace();listbroadcast(jsonObjec
25、t_send.toString();廣播List的方法private static void listbroadcast(String msg) for (ChatAnnotation client : connections) / 每個客戶端都發(fā)送一遍try 10synchronized (client) client.session.getBasicRemote().sendText(list + msg); catch (IOException e) System. out.println(在線列表顯示出錯);前端解析如下:過程為先將接收到的消息進行過濾,如果為用于更新list的消息,則
26、進行解析。將獲取到 的字符串轉(zhuǎn)換成一個JSON對象,解析整個JSON對象,獲取到在線列表,輸出到列表框中。var receivedMsg = message.data;if (receivedMsg.startsWith(list) receivedMsg = receivedMsg.substring(4);var obj = JSON.parse(receivedMsg);var print = ”;for (var i = 0; i obj.list.length; i+) print = print + +obj.listi+在 線 +;print=print+“”;document.
27、getElementById(listbox).innerHTML = print;私聊功能:后臺接收到要進行私聊的命令,過濾之后得到talkToName,設(shè)置當前用戶的TalkTo、 PrivateChat屬性。遍歷users集合,獲取到要私聊對象的user類,將其TalkTo、PrivateChat 屬性也進行相應(yīng)的設(shè)置,同是私聊對象的chatAnnotation將作為參數(shù)傳至廣播方法 privateBroadcast(String ,ChatAnnotation )。if (message.startsWith(+&) String talkToName=message.substrin
28、g(2);/獲得想要私聊的對象名字user.setTalkTo(talkToName);user.setPrivateChat(true);System. out.println(talkToName+talkToName);ChatAnnotation chatAnnotation=null;for (int i=0;iusers.size();i+) if (users.get(i).getName().equals(talkToName) users.get(i).setTalkTo(user.getName();users.get(i).setPrivateChat(true);cha
29、tAnnotation=users.get(i).getChatAnnotation();System. out.println(要私聊的名字是+user.getTalkTo(); break;privateBroadcast(user.getName()+”和進入+user.getTalkTo()+”進入私聊模式“,chatAnnotation);11return;私聊廣播方法:實現(xiàn)只將消息廣播給本人以及要私聊的對象。private void privateBroadcast(String string,ChatAnnotation chatAnnotation) if (chatAnnot
30、ation=null) try System. out.println(對方不存在!);this. session.getBasicRemote().sendText (對方不存在!”); catch (IOException e) e.printStackTrace();return;else try System. out.println(私聊);chatAnnotation. session.getBasicRemote().sendText(system : + string);this.session.getBasicRemote().sendText(system : + stri
31、ng);return; catch (IOException e) e.printStackTrace();遇到的問題及解決方案問題:在實現(xiàn)私聊的過程中,在后臺想要獲取所要私聊對象的user類以及其chatAnnotation對象,結(jié)果 發(fā)現(xiàn)獲取到的user為空。然后開始逐步調(diào)試,結(jié)果沒發(fā)現(xiàn)問題。后來打算把所有的user信息作為物理信息存在文件中,在改版快完成的時候,發(fā)現(xiàn)方法內(nèi)和方法 外各new 了一個user對象,導(dǎo)致我所使用的user為空值。解決方案:刪除全局的user,保留方法內(nèi)的user對象。4.實踐總結(jié).加深了 HTTP協(xié)議,F(xiàn)TP協(xié)議的理解,使得之前停留在書本層面的知識變成了實踐,
32、 對今后的實踐會產(chǎn)生積極的影響;.熟練使用JAVA的多線程,網(wǎng)絡(luò)編程。多線程的使用將解決應(yīng)用單用戶連接的尷尬 局面,多線程將能開發(fā)出真正能夠被廣泛使用的程序,程序的邏輯設(shè)計才能化為實 際生產(chǎn)力;.提升了 JAVA編程的動手和調(diào)試能力,JAVA調(diào)試代碼不僅僅是簡單的設(shè)置斷點、步 進調(diào)試,調(diào)試代碼需要技巧,巧妙設(shè)置斷點能是調(diào)試代碼效率提升數(shù)倍,同時加深 對JAVA代碼執(zhí)行的理解。4,熟悉了結(jié)構(gòu)流程圖的畫法,雖然畫的流程圖不是非常標準,但是很努力的在將程序12中的邏輯通過結(jié)構(gòu)化的呈現(xiàn)表達出來,這也是一大收獲;5,熟悉了 JSON的使用,在傳遞數(shù)據(jù)的時候?qū)⒆址庋b成JSON格式,一是對于多 平臺的適用,二是對方法的簡化、標準化,三是減少代碼的出
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024污水泵銷售、安裝及水質(zhì)達標驗收服務(wù)合同3篇
- DB46T-椰子建園技術(shù)規(guī)程
- 2024年網(wǎng)絡(luò)安全咨詢服務(wù)合同5篇
- 2024旅游服務(wù)合同景點門票包含內(nèi)容
- 2024年高端釩鈦產(chǎn)品生產(chǎn)線施工合同
- 2024年版權(quán)使用費用授權(quán)合同
- 2024年物業(yè)權(quán)益買賣合同模板3篇
- 藥學(xué)畢業(yè)論文
- 2024年生態(tài)環(huán)境治理項目土方開挖合作合同3篇
- 職業(yè)教育實踐教學(xué)的策略及實施路徑
- 貼面 貼面修復(fù)
- 2023年高二學(xué)業(yè)水平測試生物模擬考試試題
- 力士樂-mtx micro簡明安裝調(diào)試手冊v4updated
- GB/T 6807-2001鋼鐵工件涂裝前磷化處理技術(shù)條件
- GB/T 15109-1994白酒工業(yè)術(shù)語
- 膜片鉗常見問題匯總(人人都會膜片鉗)
- 校車安全逃生技能培訓(xùn)學(xué)習
- (新版)電網(wǎng)規(guī)劃專業(yè)知識考試題庫(含答案)
- 學(xué)校心理危機干預(yù)流程圖
- 杏醬生產(chǎn)工藝
- 融資擔保業(yè)務(wù)風險分類管理辦法
評論
0/150
提交評論