




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
精選優(yōu)質(zhì)文檔-----傾情為你奉上精選優(yōu)質(zhì)文檔-----傾情為你奉上專心---專注---專業(yè)專心---專注---專業(yè)精選優(yōu)質(zhì)文檔-----傾情為你奉上專心---專注---專業(yè)一、設(shè)計思想本課程設(shè)計主要是基于UDP的并用Java實現(xiàn)的簡單的聊天程序。UDP
用戶數(shù)據(jù)報是在運輸層的端到端抽象的邏輯信道中傳送的。UDP
在傳送數(shù)據(jù)之前不需要先建立連接。對方的運輸層在收到
UDP
報文后,不需要給出任何確認。雖然
UDP
不提供可靠交付,但在某些情況下
UDP
是一種最有效的工作方式。雖然UDP
用戶數(shù)據(jù)報只能提供不可靠的交付,但
UDP
在某些方面有其特殊的優(yōu)點,它有即時通信的功能。比如說,使用聊天程序聊天的時候,省去的了跟對方通信的時候的鏈接的麻煩,直接進行通信。UDP
只在
IP
的數(shù)據(jù)報服務(wù)之上增加了很少一點的功能,即端口的功能和差錯檢測的功能。UDP
使用盡最大努力交付,即不保證可靠交付,同時也不使用擁塞控制。UDP
是面向報文的。UDP
沒有擁塞控制,很適合多媒體通信的要求。UDP
支持一對一、一對多、多對一和多對多的交互通信。發(fā)送方
UDP
對應(yīng)用程序交下來的報文,在添加首部后就向下交付
IP
層。UDP
對應(yīng)用層交下來的報文,既不合并,也不拆分,而是保留這些報文的邊界。應(yīng)用層交給
UDP
多長的報文,UDP
就照樣發(fā)送,即一次發(fā)送一個報文。接收方
UDP
對
IP
層交上來的
UDP
用戶數(shù)據(jù)報,在去除首部后就原封不動地交付上層的應(yīng)用進程,一次交付一個完整的報文。Socket又稱作套接字,它是使用標準Unix文件描述符(filedescriptor)和其它程序通訊的方式。使用send()和recv()讓你更好的控制數(shù)據(jù)傳輸。在Java網(wǎng)絡(luò)編程中,socket相當于應(yīng)用程序的港口碼頭;在計算機網(wǎng)絡(luò)中,套接字由ip地址和端口號組成,為進程之間通信提供地址。兩個主機進行通信實際上就是兩個主機中的應(yīng)用進程互相通信,應(yīng)用進程之間的通信又稱為端到端的通信。為應(yīng)用進程之間的通信提供運輸服務(wù)的是運輸層的運輸協(xié)議,運輸層需要有兩種不同的運輸協(xié)議,即面向連接的TCP和無連接的UDP。在Java中,用于實現(xiàn)基于UDP的聊天程序,使用兩個重要的類(DatagramSocket類和DatagramPacket類)。DatagramSocket類表示用來發(fā)送和接收數(shù)據(jù)報包的套接字。數(shù)據(jù)報套接字是包投遞服務(wù)的發(fā)送或接收點。每個在數(shù)據(jù)報套接字上發(fā)送或接收的包都是單獨編址和路由的。從一臺機器發(fā)送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。在DatagramSocket上總是啟用UDP廣播發(fā)送。為了接收廣播包,應(yīng)該將DatagramSocket綁定到通配符地址。在某些實現(xiàn)中,將DatagramSocket綁定到一個更加具體的地址時廣播包也可以被接收。DatagramPacket類表示數(shù)據(jù)報包。數(shù)據(jù)報包用來實現(xiàn)無連接包投遞服務(wù)。每條報文僅根據(jù)該包中包含的信息從一臺機器路由到另一臺機器。從一臺機器發(fā)送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。不對包投遞做出保證。服務(wù)程序工作在服務(wù)器的某個端口上,一旦啟動服務(wù),它將在這個端口上監(jiān)聽,等待客戶程序發(fā)來請求,當有客戶連接到該端口,accept()方法就返回一個Socket對象,可以用該對象獲得一個輸入輸出流。服務(wù)器的套接字用服務(wù)器套接字類(ServerSocket)來建立。具體實現(xiàn)如下:建立一個服務(wù)者,端口為5000。(2)服務(wù)者永遠等待,一旦客戶送來正確的請求,連接至該端口,accept()方法就返回一個Socket對象。(3)用返回的Socket對象創(chuàng)建數(shù)據(jù)輸入流類的實例in。用返回的Socket對象創(chuàng)建數(shù)據(jù)輸出流的實例out。以上實例in和out是服務(wù)者用于從客戶接受輸入信息和向客戶程序發(fā)送信息所用。此外,還需要用方法readline()和println()讀取或輸出一行數(shù)據(jù)。(4)soc.close()關(guān)閉Socket。算法流程圖本程序的核心算法流程圖如下圖所示:用戶1用戶1封裝數(shù)據(jù)報解析數(shù)據(jù)報目的IP與主機IP比較接受消息用戶2是否傳輸數(shù)據(jù)報丟棄發(fā)送數(shù)據(jù)報圖1程序算法流程圖三、源代碼importjava.awt.AWTEvent;importjava.awt.Color;importjava.awt.Dimension;importjava.awt.Rectangle;importjava.awt.TextArea;importjava.awt.Toolkit;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.WindowEvent;importjava.io.IOException;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;importjavax.swing.JButton;importjavax.swing.JCheckBox;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JOptionPane;importjavax.swing.JPanel;importjavax.swing.JTextField;@SuppressWarnings("serial")publicclassUDPextendsJFrame{ //創(chuàng)建主界面 staticJPanelmainPane; //創(chuàng)建“發(fā)送信息”標簽 JLabelsendMSGLabel=newJLabel("發(fā)送信息:"); //創(chuàng)建“輸入對方ip地址”標簽 JLabelipAddressLabel=newJLabel(); //創(chuàng)建“群聊”標簽 JLabelqunLabel=newJLabel("群聊"); //創(chuàng)建發(fā)送文本框 JTextFieldsendMSGText=newJTextField(); //創(chuàng)建ip文本框 JTextFieldipAddressText=newJTextField(); //創(chuàng)建“發(fā)送”按鈕 JButtonsendMSGButton=newJButton("發(fā)送"); //創(chuàng)建“群聊”選擇框 JCheckBoxqunCB=newJCheckBox(); //創(chuàng)建聊天信息文本框 staticTextAreaMSGText=newTextArea(); //輸入端口 intIn=3001; //輸出端口 intOut=3000; //聲明發(fā)送和接收數(shù)據(jù)包引用 staticDatagramPacketsendDP,getDP; //聲明發(fā)送和接收套接字引用 staticDatagramSocketsendDS,getDS; //界面開關(guān) staticbooleanpackFrame=false; //群聊開關(guān) staticbooleanisQun=false; //程序主方法 publicstaticvoidmain(String[]args){ //創(chuàng)建UDP類實例 UDPframe=newUDP(); //判定主界面是否以創(chuàng)建 if(packFrame){ frame.pack(); }else{ frame.validate(); } //放置窗體在屏幕中央 DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize(); DimensionframeSize=frame.getSize(); if(frameSize.height>screenSize.height){ frameSize.height=screenSize.height; } if(frameSize.width>screenSize.width){ frameSize.width=screenSize.width; } frame.setLocation((screenSize.width-frameSize.width)/2, (screenSize.height-frameSize.height)/2); frame.setVisible(true); //接受局域網(wǎng)消息 while(true){ try{ //創(chuàng)建接受字符串 Stringreceived=null; //創(chuàng)建接受數(shù)組 byte[]array=newbyte[100]; //創(chuàng)建接受數(shù)據(jù)包 getDP=newDatagramPacket(array,array.length); //創(chuàng)建接受套接字 getDS.receive(getDP); //判定消息是否為群發(fā) if(!getDP .getAddress() .toString() .equals("/"+InetAddress.getLocalHost().getHostAddress() .toString())){ //如果為私聊,則顯示以下消息 MSGText.append("\n"+getDP.getAddress().toString().substring(1)+"說:"); received=newString(getDP.getData(),0, getDP.getLength(),"UTF-8"); MSGText.append(received); } //捕獲異常 }catch(IOExceptionse){ se.printStackTrace(); } } } //重構(gòu)構(gòu)造方法 publicUDP(){ enableEvents(AWTEvent.WINDOW_EVENT_MASK); try{ //構(gòu)建主窗體 mainPane=(JPanel)this.getContentPane(); //設(shè)置主窗體的布局 mainPane.setLayout(null); //設(shè)置主窗體的大小 this.setSize(newDimension(363,500)); //設(shè)置標題 this.setTitle("基于UDP的局域網(wǎng)聊天室"); //設(shè)置ip輸入框的文字為“輸入對方IP地址” ipAddressLabel.setText("輸入對方IP地址:"); //設(shè)置ip地址標簽的位置 ipAddressLabel.setBounds(newRectangle(12,20,109,23)); //設(shè)置ip地址輸入框的位置 ipAddressText.setBounds(newRectangle(123,20,120,19)); //設(shè)置群聊標簽的位置 qunLabel.setBounds(270,20,40,20); //設(shè)置群聊選擇框的位置 qunCB.setBounds(295,20,20,20); //為群聊選擇框添加監(jiān)聽器 qunCB.addActionListener(newActionListener(){ //重寫處理方法 @Override publicvoidactionPerformed(ActionEvente){ //將群聊選擇框反選 isQun=!isQun; //設(shè)置ip地址輸入框為不可用 ipAddressText.setEditable(!isQun); } }); //設(shè)置聊天記錄框的位置 MSGText.setBounds(newRectangle(11,60,333,355)); //設(shè)置聊天記錄框為可用 MSGText.setEditable(false); //設(shè)置聊天記錄框背景色為白色 MSGText.setBackground(Color.white); //設(shè)置發(fā)送消息標簽的位置 sendMSGLabel.setBounds(newRectangle(13,430,65,20)); //設(shè)置發(fā)送文本框的位置 sendMSGText.setBounds(newRectangle(80,430,190,20)); //設(shè)置發(fā)送按鈕的位置 sendMSGButton.setBounds(newRectangle(280,430,65,20)); //添加發(fā)送按鈕的監(jiān)聽器 sendMSGButton .addActionListener(newjava.awt.event.ActionListener(){ //重寫處理方法 publicvoidactionPerformed(ActionEvente){ try{ //判定是否為群聊消息 if(isQun){ //如果是群聊,則顯示以下消息 MSGText.append("\n您對大家說:" +sendMSGText.getText()); //創(chuàng)建比特數(shù)組 bytedata[]=sendMSGText.getText() .getBytes("UTF-8"); //創(chuàng)建數(shù)據(jù)包 sendDP=newDatagramPacket( //數(shù)據(jù) data, //數(shù)據(jù)長度 data.length, //ip地址 InetAddress .getByName("55"), //輸出端口 In); //發(fā)送數(shù)據(jù)包 sendDS.send(sendDP); }else{ //如果是私聊,則顯示以下消息 MSGText.append("\n您對" +ipAddressText.getText()+"說:" +sendMSGText.getText()); //創(chuàng)建比特數(shù)組 bytedata[]=sendMSGText.getText() .getBytes("UTF-8"); //創(chuàng)建數(shù)據(jù)包 sendDP=newDatagramPacket( //數(shù)據(jù) data, //數(shù)據(jù)長度 data.length, //ip地址 InetAddress.getByName(ipAddressText .getText()), //輸出端口 In); //發(fā)送數(shù)據(jù)包 sendDS.send(sendDP); } //捕獲異常 }catch(IOExceptionexc){ System.out.println("您不在局域網(wǎng)!"); } //清空發(fā)送消息文本框內(nèi)容 sendMSGText.setText(""); } }); //把ip地址標簽添加進主界面 mainPane.add(ipAddressLabel,null); //把發(fā)送消息標簽添加進主界面 mainPane.add(sendMSGLabel,null); //把發(fā)送消息文本框添加進主界面 mainPane.add(sendMSGText,null); //把ip地址輸入框添加進主界面 mainPane.add(ipAddressText,null); //把消息記錄框添加進主界面 mainPane.add(MSGText,null); //把發(fā)送按鈕添加進主界面 mainPane.add(sendMSGButton,null); //把群聊標簽添加進主界面 mainPane.add(qunLabel,null); //把群聊選擇框添加進主界面 mainPane.add(qunCB); //設(shè)置各組件為可見 this.setVisible(true); try{ //創(chuàng)建發(fā)送端口套接字 sendDS=newDatagramSocket(Out); //創(chuàng)建接受端口套接字 getDS=newDatagramSocket(In); //異常捕獲 }catch(SocketExceptionse){ se.printStackTrace(); //捕獲異常后退出系統(tǒng) System.exit(0); } //捕獲異常 }catch(Exceptione){ e.printStackTrace(); } } //重載關(guān)閉按鈕函數(shù) protectedvoidprocessWindowEvent(WindowEvente){ cessWindowEvent(e); if(e.getID()==WindowEvent.WINDOW_CLOSING){ System.exit(0); } }}運行結(jié)果軟件運行出事界面如下:圖2軟件初始界面之后輸入對方ip地址,在下面的輸入框內(nèi)輸入想要說的文字:圖3輸入ip地址點擊“發(fā)送”按鈕,發(fā)送消息:圖4點擊“發(fā)送”按鈕接收到對方的信息:圖5收到對方私聊信息勾選群聊選項,輸入想說的話:圖6發(fā)送群聊信息收到其他人的群聊信息:圖7收到群聊信息五、遇到的問題及解決這部分我主要遇到了如下兩個問題,其內(nèi)容與解決方法如下所列:1.程序無法發(fā)送和接收數(shù)據(jù)解決方法:沒有弄明白DatagramPacket和DatagramSocket的用法和區(qū)別。DatagramPacket和DatagramSocket都存在中。DatagramPacket表示存放數(shù)據(jù)的數(shù)據(jù)報,DatagramSocket表示接受或發(fā)送數(shù)據(jù)報的套接字。DatagramPacket實例,并將其作為參數(shù)傳遞給DatagramSocket類的send()方法。接收信息時,Java程序首先創(chuàng)建一個DatagramPacket實例,該實例中預(yù)先分配了一些空間(一個字節(jié)數(shù)組byte[]),并將接收到的信息存放在該空間中。然后把該實例作為參數(shù)傳遞給DatagramSocket類的receive()方法。除傳輸?shù)男畔⒈旧硗?,每個DatagramPacket實例中還附加了地址和端口信息,其具體含義取決于該數(shù)據(jù)報文是被發(fā)送還是被接收。若是要發(fā)送的數(shù)據(jù)報文,DatagramPacket實例中的地址則指明了目的地址和端口號,若是接收到的數(shù)據(jù)報文,DatagramPacket實例中的地址則指明了所收信息的源地址。因此,服務(wù)器端可以修改接收到的DatagramPacket實例的緩存區(qū)內(nèi)容,再將這個實例連同修改后的信息一起,發(fā)回給它的源地址。Java使用DatagramSocket代表UDP協(xié)議的Socket,DatagramSocket本身只是碼頭,不維護狀態(tài),不能產(chǎn)生IO流,它的唯一作用就是接收和發(fā)送數(shù)據(jù)報,Java使用DatagramPacket來代表數(shù)據(jù)報,DatagramSocket接收和發(fā)送的數(shù)據(jù)都是通過DatagramPacket對象完成的。2.在程序中加入圖片,用代碼讀取圖片路徑設(shè)置為絕對路徑,導(dǎo)致程序移動之后,圖片文件無法被讀取。解決辦法:從網(wǎng)上搜索資料,參考大神博客,真正理解什么是絕對路徑和相對路徑的區(qū)別以及在項目開發(fā)中用法的不同。所謂的絕對路徑,就是文件在整個文件系統(tǒng)的全路徑,如在Windows下,D:\JAVA\MyEclipse\MyEclipse10這個文件夾或者D:\JAVA\MyEclipse\MyEclipse10\myeclipse.exe這個文件,都是以全路徑名的形式出現(xiàn)的。只是在Java代碼中,\是必須轉(zhuǎn)義的,所以我們寫絕對路徑時,總會D:\\JAVA\MyEclipse\\MyEclipse10\\myeclipse.exe。如代碼中:Filefile04=newFile("C:\\test1\\test101\\SeProjectFileDemo04.txt");Filefile05=newFile(dirAbsPath05,"SeProjectFileDemo05.txt");這兩種都是絕對路徑的寫法,其中前者中C:\\test1\\test101\\的目錄必須事先已經(jīng)存在者兩個目錄,后者dirAbsPath05也必須是已經(jīng)創(chuàng)建好的目錄,如代碼中就Filedir05=newFile("C:\\test2\\test201");if(!dir05.exists())dir05.mkdirs();所謂的相對路徑,就是相對某個目錄的情況下,某個資源文件的短名稱,這其中就涉及到參考誰的問題了。如:如果我說,以后你們寫相對路徑,都是以D:\\JAVA\MyEclipse\\MyEclipse10這個目錄為參考點,那么Filefile=newFile("myeclipse.exe");中的"myeclipse.exe"就是一個相對路徑的寫法。六、心得體會這次的課程設(shè)計,我覺得還是很成功的。先是成功實現(xiàn)了此次設(shè)計的要求,另外我還添加了群聊功能。一開始并不打算選這個題目的時候,后來只是抱著試試看的心理,這部分的知識應(yīng)該說是沒有學(xué)過,老師上課也沒有講這個SOCKET套接字的部分,是要我們課后自己看的。我只好把書上的一段基于客戶-服務(wù)器端的計算三角形面積的java代碼先調(diào)試一下,熟悉一下代碼運行的效果,給我一點思路。再根據(jù)這個程序的框架,來編寫代碼,但是后來發(fā)現(xiàn)自己編代碼并不簡單,折騰了好久也沒成功,覺得自己的設(shè)計思路有點偏差,所以才導(dǎo)致這個程序的失敗,看來把理論變成實踐可真不是一件簡簡單單就能完成的事。
接下來的幾
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 中國造影劑行業(yè)市場發(fā)展監(jiān)測及投資戰(zhàn)略規(guī)劃研究報告
- 2025年隔墻板生產(chǎn)設(shè)備維護與保養(yǎng)服務(wù)合同
- 中國鉛渣項目投資可行性研究報告
- 中國阿氯米松項目投資可行性研究報告
- Unit5 What an adventure!Understanding ideas Climbing Qomolangma Worth the risks教學(xué)設(shè)計-2023-2024學(xué)年高中英語外研版(2019)必修第三冊
- 素茶食行業(yè)深度研究報告
- 上海-實驗九-2023-2024學(xué)年高中信息技術(shù)選擇性必修1(滬科版2019)-教學(xué)設(shè)計-實現(xiàn)查找指定商品-查找算法的應(yīng)用及數(shù)據(jù)結(jié)構(gòu)的選擇
- 數(shù)字光盤錄放機行業(yè)市場發(fā)展及發(fā)展趨勢與投資戰(zhàn)略研究報告
- 加強煤炭企業(yè)物資管理提升企業(yè)經(jīng)濟效益
- 27《我的伯父魯迅先生》教學(xué)設(shè)計-2024-2025學(xué)年六年級上冊語文統(tǒng)編版
- 學(xué)校小賣部承包合同范文
- 2025年湖南鐵道職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測試近5年常考版參考題庫含答案解析
- DB 63- T993-2011 三江源生態(tài)監(jiān)測技術(shù)規(guī)范
- 北京市東城區(qū)2025年公開招考539名社區(qū)工作者高頻重點提升(共500題)附帶答案詳解
- 2025至2030年中國電子護眼臺燈數(shù)據(jù)監(jiān)測研究報告
- 2025年浙江省溫州樂清市融媒體中心招聘4人歷年高頻重點提升(共500題)附帶答案詳解
- 2025夏季廣東廣州期貨交易所招聘高頻重點提升(共500題)附帶答案詳解
- 2025上海市嘉定工業(yè)區(qū)農(nóng)村青年干部招聘22人歷年高頻重點提升(共500題)附帶答案詳解
- 《獸醫(yī)基礎(chǔ)》練習(xí)題及參考答案
- 2025年煤礦探放水證考試題庫
- 農(nóng)業(yè)機械設(shè)備運輸及調(diào)試方案
評論
0/150
提交評論