第4章數(shù)據(jù)報套接字_第1頁
第4章數(shù)據(jù)報套接字_第2頁
第4章數(shù)據(jù)報套接字_第3頁
第4章數(shù)據(jù)報套接字_第4頁
第4章數(shù)據(jù)報套接字_第5頁
已閱讀5頁,還剩138頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第4章數(shù)據(jù)報套接字2023/2/21Java網(wǎng)絡程序設計本章概述數(shù)據(jù)報套接字(datagramsocket),又稱自尋址套接字。自尋址使用UDP發(fā)送尋址信息(從客戶程序到服務程序或從服務程序到客戶程序),不同的是可以通過自尋址套接字發(fā)送多IP信息包,自尋址信息包含在自尋址包中Datagram(數(shù)據(jù)報)是一種盡力而為(best-effort)的傳送數(shù)據(jù)的方式它只是把數(shù)據(jù)的目的地記錄在數(shù)據(jù)包(DatagramPacket)中,然后就直接放在網(wǎng)絡上,系統(tǒng)不保證數(shù)據(jù)是否能安全送到,或者什么時候可以送到,也就是說它并不保證傳送質(zhì)量2023/2/22Java網(wǎng)絡程序設計本章概述數(shù)據(jù)報套接字基于的是UDP協(xié)議,與TCP保證信息到達信息目的地的方式不同,UDP提供了另外一種方法,如果自尋址信息包沒有到達目的地,UDP也不會請求發(fā)送者重新發(fā)送自尋址包自尋址套接字工作包括下面三個類:DatagramPacket描繪了自尋址包的地址信息DatagramSocket表示客戶程序和服務器程序自 尋址套接字MulticastSocket描繪進行多點傳送的自尋址套接字這三個類均位于包內(nèi)2023/2/23Java網(wǎng)絡程序設計4.1數(shù)據(jù)報套接字數(shù)據(jù)報(Datagram)是網(wǎng)絡層數(shù)據(jù)單元在介質(zhì)上傳輸信息的一種邏輯分組格式,它是一種在網(wǎng)絡中傳播的、獨立的、自身包含地址信息的消息,它能否到達目的地、到達的時間、到達時內(nèi)容是否會變化不能準確地知道DatagramSocket本身只是碼頭,不維護狀態(tài),不能產(chǎn)生I/O流,它的唯一作用就是接收和發(fā)送數(shù)據(jù)報,Java使用DatagramPacket來代表數(shù)據(jù)報,DatagramSocket接收和發(fā)送的數(shù)據(jù)都是通過DatagramPacket對象完成的。2023/2/24Java網(wǎng)絡程序設計4.1數(shù)據(jù)報套接字它的通信雙方是不需要建立連接的,對于一些不需要很高質(zhì)量的應用程序來說,數(shù)據(jù)報通信是一個非常好的選擇。在Java的包中有兩個類DatagramSocket和DatagramPacket,為應用程序中采用數(shù)據(jù)報通信方式進行網(wǎng)絡通信。2023/2/25Java網(wǎng)絡程序設計4.1.1創(chuàng)建DatagramPacket對象使用數(shù)據(jù)包方式發(fā)送信息,首先將數(shù)據(jù)打包,包中的DategramPacket類用來創(chuàng)建數(shù)據(jù)包。數(shù)據(jù)包有兩種:一種是用來被發(fā)送的數(shù)據(jù)包,該數(shù)據(jù)包有要傳遞到的目的地址;另一種數(shù)據(jù)包用來接收傳遞過來的數(shù)據(jù)包中的數(shù)據(jù)。2023/2/26Java網(wǎng)絡程序設計1.創(chuàng)建的DatagramPacket對象用于接收數(shù)據(jù)1)publicDatagramPacket(byteibuf[],intilength)

以一個空數(shù)組來創(chuàng)建DatagramPacket對象,該對象的作用是接收DatagramSocket中的數(shù)據(jù)。2)publicDatagramPacket(byteibuf[],intoffset,intilength):

以一個空數(shù)組來創(chuàng)建DatagramPacket對象,并指定接收到的數(shù)據(jù)放入ibuf數(shù)組中時從offset開始,最多放ilength個字節(jié)。2023/2/27Java網(wǎng)絡程序設計1.創(chuàng)建的DatagramPacket對象用于接收數(shù)據(jù)如:byte[]buffer=newbyte[8912];DatagramPacketdatap=newDatagramPacket(buffer,buffer.length());2023/2/28Java網(wǎng)絡程序設計2.創(chuàng)建的DatagramPacket對象用于發(fā)送數(shù)據(jù)1)publicDatagramPacket(bytibuf[],intilength,InetAddrssiaddr,intport)以一個包含數(shù)據(jù)的數(shù)組來創(chuàng)建DatagramPacket對象,創(chuàng)建該DatagramPacket時還指定了IP地址和端口號——這就決定了該數(shù)據(jù)報的目的地址。2)publicDatagramPacket(bytibuf[],intoffset,intilength,InetAddrssiaddr,intport)創(chuàng)建一個用于發(fā)送的DatagramPacket對象,也多指定了一個offset參數(shù)。

2023/2/29Java網(wǎng)絡程序設計2.創(chuàng)建的DatagramPacket對象用于發(fā)送數(shù)據(jù)如:Strings=newString(“javanetworking”);byte[]data=s.getbytes();intport=1024;try{InetAddressineta=InetAddress.getByName(“4”);DatagramPacketdatap=newDatagramPacket(data,data.length(),ineta,port);}catch(IOExceptioe){}2023/2/210Java網(wǎng)絡程序設計4.1.1創(chuàng)建DatagramPacket對象當服務器(也可以是客戶端)接收到一個DategramPacket對象后,如果想向該數(shù)據(jù)報的發(fā)送者“反饋”一些信息,但由于UDP是面向非連接的,所以接收者并不知道每個數(shù)據(jù)報由誰發(fā)送過來,但程序可以調(diào)用DategramPacket的方法來獲取發(fā)送者的IP地址和端口號。下面我們來看DategramPacket的常用方法。2023/2/211Java網(wǎng)絡程序設計4.1.2DatagramPacket的常用方法(1)publicbyte[]getData()

返回一個字節(jié)數(shù)組,其中是數(shù)據(jù)包的數(shù)據(jù)。如果想把字節(jié)數(shù)組轉(zhuǎn)換成別的類型就要進行轉(zhuǎn)化。(2)publicInetAddressgetAddress()

返回某臺機器的IP地址,當程序準備發(fā)送數(shù)據(jù)報時,該方法返回此數(shù)據(jù)報的目標機器的IP地址;當程序剛剛接收到一個數(shù)據(jù)報時,該方法返回該數(shù)據(jù)報的發(fā)送主機的IP地址。(3)publicbyte[]getLength()

獲得數(shù)據(jù)報中數(shù)據(jù)的字節(jié)數(shù)。2023/2/212Java網(wǎng)絡程序設計4.1.2DatagramPacket的常用方法(4)pubicintgetPort()

返回某臺機器的端口號,當程序員準備發(fā)送此數(shù)據(jù)報時,該方法返回此數(shù)據(jù)報的目標機器的IP地址;當程序員剛剛接收到一個數(shù)據(jù)報時主,該方法返回數(shù)據(jù)報的發(fā)送主機的IP地址。(5)pubicSocketAddressgetSocketAddress()

返回要將此包發(fā)送到的或此數(shù)據(jù)報的遠程主機的SocketAddress(通常為IP地址+端口號)

(6)pubicintgetOffset()

返回將發(fā)送或接收的數(shù)據(jù)的偏移量2023/2/213Java網(wǎng)絡程序設計4.1.2DatagramPacket的常用方法設置DatagramPacket對象屬性的方法如下:(1)publicvoidsetAddress(InetAddressiaddr)

設置要將此數(shù)據(jù)報發(fā)往的那臺機器的IP地址。(2)publicvoidsetData(byte[]buf)

為此包設置數(shù)據(jù)緩沖區(qū)。(3)publicvoidsetData(byte[]buf,intoffset,intlength)

為此包設置數(shù)據(jù)緩沖區(qū)。(4)publicvoidsetLength(intlength)

為此包設置長度。2023/2/214Java網(wǎng)絡程序設計4.1.2DatagramPacket的常用方法(5)publicvoidsetPot(intport)

設置要將此數(shù)據(jù)報發(fā)往的遠程主機上的端口號。(6)publicvoidsetSocketAddress(SocketAddressaddress)

為此要將地數(shù)據(jù)報發(fā)往的遠程主機的SocketAddress(通常為IP地址+端口號)。2023/2/215Java網(wǎng)絡程序設計4.1.3創(chuàng)建DatagramSocket對象發(fā)送和接收數(shù)據(jù)包還需要發(fā)送和接收數(shù)據(jù)包的數(shù)據(jù)報套接字,即DatagramSocket對象,DatagramSocket在本地機器端口監(jiān)聽是否有數(shù)據(jù)到達或者將數(shù)據(jù)包發(fā)送出去。(1)publicDatagramSocket()

用本地機器上任何一個可用的端口創(chuàng)建一個數(shù)據(jù)報套接字,這個端口號是由系統(tǒng)隨機產(chǎn)生的。這種構造方法沒有指定端口號,可以用在客戶端。如果構造不成功則觸發(fā)SocketException異常。2023/2/216Java網(wǎng)絡程序設計4.1.3創(chuàng)建DatagramSocket對象(2)publicDatagramSocket(intport)

用一個指定的端口號port創(chuàng)建一個數(shù)據(jù)報套接字。當不能創(chuàng)建數(shù)據(jù)報套接字時就拋出SocketException異常,其原因是指定的端口已被占用或者是試圖連接低于1024的端口,但是又沒有具備權限。(3)publicDatagramSocket(intport,InetAddressladdr)

創(chuàng)建一個DatagramSocket對象,并將該對象綁定到指定的IP地址和端口。2023/2/217Java網(wǎng)絡程序設計4.1.4DatagramSocket的常用方法一旦得到了DatagramSocket對象之后,就可以通過如下兩個方法來接收和發(fā)送數(shù)據(jù):(1)publicvoid

receive(DatagramPacketp)從該DatagramSocket中接收數(shù)據(jù)報。(2)publicvoidsend(DatagramPacketp)以該DatagramSocket對象向外發(fā)送數(shù)據(jù)報。2023/2/218Java網(wǎng)絡程序設計4.1.4DatagramSocket的常用方法從上面兩個方法可以看出,使用DatagramSocket發(fā)送數(shù)據(jù)報時,DatagramSocket并不知道將該數(shù)據(jù)報發(fā)送到哪里,而是由DatagramPacket自身決定數(shù)據(jù)報的目的地。就像碼頭并不知道每個集裝箱的目的地,碼頭只是將這些集裝箱發(fā)送出去,而集裝箱本身包含了該集裝箱的目的地。除此之外,DatagramSocket還有一些常用方法:(3)publicInetAddressgetLocalAddress()獲取數(shù)據(jù)報套接字綁定的本地IP地址。(4)publicintgetLocalPort()返回數(shù)據(jù)報套接字綁定的本地主機上的端口。2023/2/219Java網(wǎng)絡程序設計4.1.4DatagramSocket的常用方法(5)publicSocketAddressgetLocalSocketAddress()返回一個SocketAddress對象,它包含此數(shù)據(jù)報套接字綁定的IP地址和端口號。2023/2/220Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程(1)首先要建立數(shù)據(jù)報通信的Socket,我們可以通過創(chuàng)建一個DatagramSocket對象實現(xiàn)它,在Java中DatagramSocket類有如下兩種構造方法:

publicDatagramSocket()構造一個數(shù)據(jù)報socket,并使其與本地主機任一可用的端口連接。若打不開socket則拋出SocketException異常。publicDatagramSocket(intport)構造一個數(shù)據(jù)報socket,并使其與本地主機指定的端口連接。若打不開socket或socket無法與指定的端口連接則拋出SocketException異常。2023/2/221Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程(2)創(chuàng)建一個數(shù)據(jù)報文包,用來實現(xiàn)無連接的包傳送服務。每個數(shù)據(jù)報文包用DatagramPacket類創(chuàng)建,DatagramPacket對象封裝了數(shù)據(jù)報包數(shù)據(jù)、包長度、目標地址和目標端口??蛻舳艘l(fā)送數(shù)據(jù)報文包,要調(diào)用DatagramPacket類以如下形式的構造函數(shù)創(chuàng)建DatagramPacket對象,將要發(fā)送的數(shù)據(jù)和包文目的地址信息放入對象之中。DatagramPacket(bytebufferedarray[],intlength,InetAddressaddress,intport)即構造一個包長度為length的包傳送到指定主機指定端口號上的數(shù)據(jù)報文包,參數(shù)length必須小于等于bufferedarry.length。2023/2/222Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程DatagramPacket類提供了4個類獲取信息:publicbyte[]getData()返回一個字節(jié)數(shù)組,包含收到或要發(fā)送的數(shù)據(jù)報中的數(shù)據(jù)。

publicintgetLength()返回發(fā)送或接收到的數(shù)據(jù)的長度。

publicInetAddressgetAddress()返回一個發(fā)送或接收此數(shù)據(jù)報包文的機器的IP地址。publicintgetPort()返回發(fā)送或接收數(shù)據(jù)報的遠程主機的端口號。2023/2/223Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程(3)創(chuàng)建完DatagramSocket和DatagramPacket對象,就可以發(fā)送數(shù)據(jù)報文包了。發(fā)送是通過調(diào)用DatagramSocket對象的send方法實現(xiàn),它需要以DatagramPacket對象為參數(shù),將剛才封裝進DatagramPacket對象中的數(shù)據(jù)組成數(shù)據(jù)報發(fā)出。2023/2/224Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程(4)也可以接收數(shù)據(jù)報文包。

為了接收從服務器返回的結(jié)果數(shù)據(jù)報文包,我們需要創(chuàng)建一個新的DatagramPacket對象,這就需要用到DatagramPacket的另一種構造方式DatagramPacket(bytebufferedarray[],intlength),即只需指明存放接收的數(shù)據(jù)報的緩沖區(qū)和長度。2023/2/225Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程調(diào)用DatagramSocket對象的receive()方法完成接收數(shù)據(jù)報的工作,此時需要將上面創(chuàng)建的DatagramPacket對象作為參數(shù),該方法會一直阻塞直到收到一個數(shù)據(jù)報文包,此時DatagramPacket的緩沖區(qū)中包含的就是接收到的數(shù)據(jù),數(shù)據(jù)報文包中也包含發(fā)送者的IP地址,發(fā)送者機器上的端口號等信息。2023/2/226Java網(wǎng)絡程序設計4.1.5數(shù)據(jù)報套接字編程(5)處理接收緩沖區(qū)內(nèi)的數(shù)據(jù),獲取服務結(jié)果。(6)當通信完成后,可以使用DatagramSocket對象的close()方法關閉數(shù)據(jù)報通信Socket。當然,Java會自動關閉Socket,釋放DatagramSocket和DatagramPacket所占用的資源。但是作為一種良好的編程習慣,還是要顯式地予以關閉。數(shù)據(jù)報套接字通信的流程如下圖所示:2023/2/227Java網(wǎng)絡程序設計接收端(Receiver)DatagramSocket(intport)DatagramPacket(byte[]buf,intlength)DatagramSocket.receive(DatagramPacketp)DatagramSocket.close()發(fā)送端(Sender)DatagramSocket()DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)DatagramSocket.send(DatagramPacketp)DatagramSocket.close()2023/2/228Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程29/1389.2數(shù)據(jù)報程序設計2023/2/229Java網(wǎng)絡程序設計4.2DatagramSocket編程示例4.2.1利用數(shù)據(jù)報套接字查詢端口占用情況用DatagramSocket(intport)構造方法創(chuàng)建一個數(shù)據(jù)報套接字時,如果指定端口已被其他服務占用,則不能創(chuàng)建數(shù)據(jù)報套接字,且會拋出SocketException異常,我們可以利用這個異常探查本地機的端口有沒有服務。程序如下:2023/2/230Java網(wǎng)絡程序設計4.2.1利用數(shù)據(jù)報套接字查詢端口占用情況.DatagramSocket;.SocketException;publicclassUDPScan{ publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub for(intport=1024;port<=65535;port++){ try{ DatagramSocketserver=newDatagramSocket(port); server.close();

}2023/2/231Java網(wǎng)絡程序設計4.2.1利用數(shù)據(jù)報套接字查詢端口占用情況

}catch(SocketExceptione){ System.out.println("thereisaserverinport"+port+"."); } } }}2023/2/232Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器importjava.io.IOException;.DatagramPacket;.DatagramSocket;.SocketException;publicclassUDPServer{publicstaticvoidmain(String[]args){ try{ DatagramSocketreceiveSocket=newDatagramSocket(5000); bytebuf[]=newbyte[1000]; DatagramPacketreceivePacket=newDatagramPacket(buf,buf.length); System.out.println("開始接收包");2023/2/233Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器 while(true){receiveSocket.receive(receivePacket); Stringname=receivePacket.getAddress().toString(); System.out.println("\n來自主機:"+name+"\n端口:"+receivePacket.getPort()); Strings=newString(receivePacket.getData(),0,receivePacket.getLength()); System.out.println("收到的數(shù)據(jù):"+s); } }catch(SocketExceptione){ e.printStackTrace(); System.exit(1); }2023/2/234Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器 catch(IOExceptione){ System.out.println("網(wǎng)絡通信出現(xiàn)錯誤,問題在"+e.toString());}}}2023/2/235Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器importjava.io.IOException;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;publicclassUDPClient{ publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub2023/2/236Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器 try{ DatagramSocketsendSocket=newDatagramSocket(3456); Stringstring="你好!這里是客戶端"; byte[]databyte=newbyte[100]; databyte=string.getBytes(); DatagramPacketsendPacket=newDatagramPacket(databyte,string.length(),InetAddress.getByName(""),5000);2023/2/237Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器 sendSocket.send(sendPacket); System.out.println("發(fā)送數(shù)據(jù):你好!這里是客戶端"); }catch(SocketExceptione){ System.out.println("不能打開數(shù)據(jù)報Socket,或數(shù)據(jù)報Socket無法與指定端口連接!"); }2023/2/238Java網(wǎng)絡程序設計4.2.2利用數(shù)據(jù)報進行通信:創(chuàng)建UDP服務器catch(IOExceptione){ System.out.println("網(wǎng)絡通信出現(xiàn)錯誤,問題出在"+e.toString()); } }}2023/2/239Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程40/1384.2.3使用數(shù)據(jù)報套接字完成前章計算面積例客戶/服務器舉例。2023/2/240Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程41/138

importjava.io.*;.*;importjava.util.*;importjava.awt.*;importjavax.swing.*;2023/2/241Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程42/138publicclassDatagramServerextendsJFrame{//TextareafordisplayingcontentsprivateJTextAreajta=newJTextArea();//發(fā)送和接收數(shù)據(jù)報分組的字節(jié)數(shù)組privatebyte[]buf=newbyte[256];publicstaticvoidmain(String[]args){newDatagramServer();}2023/2/242Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程43/138publicDatagramServer(){//PlacetextareaontheframesetLayout(newBorderLayout());add(newJScrollPane(jta),BorderLayout.CENTER);setTitle("DatagramServer");setSize(500,300);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);2023/2/243Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程44/138

try{//CreateaserversocketDatagramSocketsocket=newDatagramSocket(8000);jta.append("Serverstartedat"+newDate()+'\n');//CreateapacketforreceivingdataDatagramPacketreceivePacket=newDatagramPacket(buf,buf.length);2023/2/244Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程45/138//CreateapacketforsendingdataDatagramPacketsendPacket=newDatagramPacket(buf,buf.length);while(true){//初始化緩沖區(qū)eachiterationArrays.fill(buf,(byte)0);2023/2/245Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程46/138//通過包接收半徑socket.receive(receivePacket);jta.append("Theclienthostnameis"+receivePacket.getAddress().getHostName()+"andportnumberis"+receivePacket.getPort()+'\n');jta.append("Radiusreceivedfromclientis"+newString(buf).trim()+'\n');//Computearea2023/2/246Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程47/138//Computeareadoubleradius=Double.parseDouble(newString(buf).trim());doublearea=radius*radius*Math.PI;jta.append("Areais"+area+'\n');//發(fā)送面積sendPacket.setAddress(receivePacket.getAddress());//設置客戶地址sendPacket.setPort(receivePacket.getPort());//設置客戶端口2023/2/247Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程48/138sendPacket.setData(newDouble(area).toString().getBytes());socket.send(sendPacket);//發(fā)送}

}

catch(IOExceptionex){ex.printStackTrace();

}}}2023/2/248Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程49/138importjava.io.*;.*;importjava.util.*;importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;publicclassDatagramClientextendsJFrame{//TextfieldforreceivingradiusprivateJTextFieldjtf=newJTextField();2023/2/249Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程50/138//TextareatodisplaycontentsprivateJTextAreajta=newJTextArea();//DatagramsocketprivateDatagramSocketsocket;//Thebytearrayforsendingandreceivingdatagrampacketsprivatebyte[]buf=newbyte[256];2023/2/250Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程51/138//ServerInetAddressprivateInetAddressaddress;//ThepacketsenttotheserverprivateDatagramPacketsendPacket;//ThepacketreceivedfromtheserverprivateDatagramPacketreceivePacket;publicstaticvoidmain(String[]args){newDatagramClient();}2023/2/251Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程52/138publicDatagramClient(){//包含標簽和文本的面板JPanelp=newJPanel();p.setLayout(newBorderLayout());p.add(newJLabel("Enterradius"),BorderLayout.WEST);p.add(jtf,BorderLayout.CENTER);jtf.setHorizontalAlignment(JTextField.RIGHT);2023/2/252Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程53/138setLayout(newBorderLayout());add(p,BorderLayout.NORTH);add(newJScrollPane(jta),BorderLayout.CENTER);jtf.addActionListener(newButtonListener());//RegisterlistenersetTitle("DatagramClient");setSize(500,300);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);2023/2/253Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程54/138setVisible(true);

try{//getadatagramsocketsocket=newDatagramSocket();address=InetAddress.getByName("localhost");sendPacket=newDatagramPacket(buf,buf.length,address,8000);receivePacket=newDatagramPacket(buf,buf.length);

}2023/2/254Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程55/138catch(IOExceptionex){ex.printStackTrace();

}}privateclassButtonListenerimplementsActionListener{publicvoidactionPerformed(ActionEvente){

try{//初始化緩沖區(qū)eachiterationArrays.fill(buf,(byte)0);2023/2/255Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程56/138//發(fā)送半徑給予服務器sendPacket.setData(jtf.getText().trim().getBytes());socket.send(sendPacket);//從服務器接收面積socket.receive(receivePacket);//顯示2023/2/256Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程57/138jta.append("Radiusis"+jtf.getText().trim()+"\n");jta.append("Areareceivedfromtheserveris"+Double.parseDouble(newString(buf).trim())+'\n');

}

catch(IOExceptionex){ex.printStackTrace();

}}}}2023/2/257Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程58/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件客戶/服務器舉例。2023/2/258Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程59/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件importjava.awt.BorderLayout;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.IOException;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;2023/2/259Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程60/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件.UnknownHostException;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassUDPChatimplementsActionListener,Runnable{2023/2/260Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程61/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件 JTextAreashowArea; JLabellbl1,lbl2,lbl3; JTextFieldmsgText,sendPortText,receivePortText,IPAddressText; JFramemainJframe; JButtonsendBtn,startBtn; JScrollPaneJSPane; JPanelpane1,pane2; Containercon; Threadthread=null;2023/2/261Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程62/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件 DatagramPacketsendPacket,receivePacket; DatagramSocketsendSocket,receiveSocket; privateInetAddresssendIP; privateintsendPort,receivePort; privatebyteinBuf[],outBuf[]; publicfinalintBUFSIZE=1024; publicUDPChat(){ mainJframe=newJFrame("聊天--UDP協(xié)議"); con=mainJframe.getContentPane(); showArea=newJTextArea(); showArea.setEditable(false);2023/2/262Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程63/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件 showArea.setLineWrap(true); lbl1=newJLabel("接收端口:"); lbl2=newJLabel("發(fā)送端口:"); lbl3=newJLabel("對方的地址:"); sendPortText=newJTextField(); sendPortText.setColumns(5); receivePortText=newJTextField(); receivePortText.setColumns(5); IPAddressText=newJTextField(); IPAddressText.setColumns(5); startBtn=newJButton("開始"); startBtn.addActionListener(this);2023/2/263Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程64/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件 pane1=newJPanel(); pane1.setLayout(newFlowLayout()); pane1.add(lbl1); pane1.add(receivePortText); pane1.add(lbl2); pane1.add(sendPortText); pane1.add(lbl3); pane1.add(IPAddressText); pane1.add(startBtn); JSPane=newJScrollPane(showArea); msgText=newJTextField(); msgText.setColumns(40);2023/2/264Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程65/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件 msgText.setEditable(false); msgText.addActionListener(this); sendBtn=newJButton("發(fā)送"); sendBtn.setEnabled(false); sendBtn.addActionListener(this); pane2=newJPanel(); pane2.setLayout(newFlowLayout()); pane2.add(msgText); pane2.add(sendBtn); con.add(pane1,BorderLayout.NORTH); con.add(JSPane,BorderLayout.CENTER);2023/2/265Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程66/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件con.add(pane2,BorderLayout.SOUTH);mainJframe.setSize(600,400);mainJframe.setVisible(true);mainJframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}

publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub newUDPChat(); }2023/2/266Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程67/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件publicvoidactionPerformed(ActionEventarg0){//TODOAuto-generatedmethodstub try{if(arg0.getSource()==startBtn){ inBuf=newbyte[BUFSIZE]; sendPort=Integer.parseInt(sendPortText.getText()); sendIP=InetAddress.getByName(IPAddressText.getText()); sendSocket=newDatagramSocket(); receivePort=Integer.parseInt(receivePortText.getText());2023/2/267Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程68/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件//創(chuàng)建接收數(shù)據(jù)包receivePacket=newDatagramPacket(inBuf,BUFSIZE);//指定接收數(shù)據(jù)的端口receiveSocket=newDatagramSocket(receivePort);//創(chuàng)建線程準備接收對方的消息thread=newThread(this);thread.setPriority(Thread.MIN_PRIORITY);thread.start();startBtn.setEnabled(false);sendBtn.setEnabled(true);2023/2/268Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程69/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件msgText.setEditable(true);

}else{ outBuf=msgText.getText().getBytes(); //組裝要發(fā)送的數(shù)據(jù)包

sendPacket=newDatagramPacket(outBuf,outBuf.length,sendIP,sendPort); //發(fā)送數(shù)據(jù)sendSocket.send(sendPacket); showArea.append("我說:"+msgText.getText()+"\n"); msgText.setText(null);}2023/2/269Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程70/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件}catch(UnknownHostExceptione){ showArea.append("無法連接到指定\n");}catch(SocketExceptione){ showArea.append("無法打開指定端口\n");}catch(IOExceptione){ showArea.append("發(fā)送數(shù)據(jù)失敗\n");}}publicvoidrun(){//TODOAuto-generatedmethodstubStringmsgstr;2023/2/270Java網(wǎng)絡程序設計楚雄師范學院計算機科學系java程序設計課程71/1384.2.4使用數(shù)據(jù)報套接字編寫聊天軟件while(true){ try{ receiveSocket.receive(receivePacket); msgstr=newString(receivePacket.getData(),0,receivePacket.getLength()); showArea.append("對方說:"+msgstr+"\n"); }catch(IOExceptione){ showArea.append("接收數(shù)據(jù)出錯\n"); }}}}2023/2/271Java網(wǎng)絡程序設計2023/2/272Java網(wǎng)絡程序設計4.3組播套接字如果服務器程序要將同一信息發(fā)送給多個客戶端,那么服務器程序和客戶程序可以利用多點傳送(multicasting)方式進行通信。2023/2/273Java網(wǎng)絡程序設計4.3組播套接字多點傳送就是服務程序?qū)S玫亩帱c傳送組的IP地址和端口發(fā)送一系列自尋址數(shù)據(jù)包,通過加入操作IP地址被多點傳送Socket注冊,通過這個點客戶程序可以接收發(fā)送給組的自尋址包(同樣客戶程序也可以給這個組發(fā)送自尋址包),一旦客戶程序讀完所有要讀的自尋址數(shù)據(jù)包,那么可以通過離開組操作離開多點傳送組。2023/2/274Java網(wǎng)絡程序設計組播套接字DatagramSocket只允許數(shù)據(jù)報發(fā)送給指定的目標地址,而MulticastSocket可以將數(shù)據(jù)報以廣播方式發(fā)送到數(shù)量不等的多個客戶端。若要使用多點廣播時,則需要讓一個數(shù)據(jù)報標有一組目標主機地址,當數(shù)據(jù)報發(fā)出后,整個組的所有主機都能收到該數(shù)據(jù)報。IP多點廣播(或多點傳送)實現(xiàn)了將單一信息發(fā)送到多個接收者的廣播,其思想是設置一組特殊網(wǎng)絡地址作為多點廣播地址,每一個多點廣播地址都被看作一個組,當客戶端需要發(fā)送、接收廣播信息時,加入到該組即可。IP協(xié)議為多點廣播2023/2/275Java網(wǎng)絡程序設計組播套接字提供了這批特殊的IP地址,這些IP地址的范圍是---55。其中~55為預留的組播地址(永久組地址),地址保留不做分配,其它地址供路由協(xié)議使用;~55是公用組播地址,可以用于Internet;~55為用戶可用的組播地址(臨時組地址),全網(wǎng)范圍內(nèi)有效;~55為本地管理組播地址,僅在特定的本地范圍內(nèi)有效。2023/2/276Java網(wǎng)絡程序設計組播套接字組播地址列表如下:基準地址(保留)所有主機的地址(包括所有路由器地址)所有組播路由器的地址不分配dvmrp路由器所有ospf路由器ospfDR/BDRst路由器st主機2023/2/277Java網(wǎng)絡程序設計組播套接字組播地址列表如下:基準地址(保留)所有主機的地址(包括所有路由器地址)所有組播路由器的地址不分配dvmrp路由器其中DVMRP(DistanceVectorMulticastRoutingProtocol)的意思是:2023/2/278Java網(wǎng)絡程序設計組播套接字距離向量多播選路協(xié)議,由單播路由協(xié)議RIP擴展而來,兩者都使用距離向量算法得到網(wǎng)絡的拓撲信息,不同之處在于RIP根據(jù)路由表前向轉(zhuǎn)發(fā)數(shù)據(jù),而DVMRP則是基于RPF。為了使新加入的組播成員能及時收到組播數(shù)據(jù),DVMPR采用定時發(fā)送數(shù)據(jù)包給所有的LAN的方法,導致大量路由控制數(shù)據(jù)包的擴散,限制了網(wǎng)絡規(guī)模的擴大。另一方面,DVMRP使用上限為32跳跳數(shù)作為計量尺度,這對網(wǎng)絡規(guī)模也是一個限制。2023/2/279Java網(wǎng)絡程序設計組播套接字rip-2路由器0Eigrp路由器1活動代理2dhcp服務器/中繼代理3所有pim路由器4rsvp封裝5所有cbt路由器6指定sbm7所有sbms8vrrp2023/2/280Java網(wǎng)絡程序設計組播套接字

以太網(wǎng)傳輸單播ip報文的時候,目的mac地址使用的是接收者的mac地址。但是在傳輸組播報文時,傳輸目的不再是一個具體的接收者,而是一個成員不確定的組,所以使用的是組播mac地址。組播mac地址是和組播ip地址對應的。iana(internetassignednumberauthority)規(guī)定,組播mac地址的高24bit為0x01005e,mac地址的低23bit為組播ip地址的低23bit。由于ip組播地址的后28位中只有23位被映射到mac地址,這樣就會有32個ip組播地址映射到同一mac地址上。。2023/2/281Java網(wǎng)絡程序設計組播套接字網(wǎng)絡應用程序接口通過MulticastSocket類及一些輔助類支持多點傳送,當一個客戶程序要加入多點傳送組時,就創(chuàng)建一個MulticastSocket對象。MulticastSocket(intport)構造函數(shù)允許應用程序指定端口(通過port參數(shù))接收自尋址包,端口必須與服務程序的端口號相匹配,要加入多點傳送組,客戶程序調(diào)用兩個joinGroup()方法中的一個;同樣要離開傳送組也需要調(diào)用兩個leaveGroup()方法中的一個。2023/2/282Java網(wǎng)絡程序設計組播套接字Java的MulticastSocket類是實施IP多點傳送網(wǎng)絡特征的關鍵,它允許我們使用多點傳送IP,發(fā)送或接收UDP數(shù)據(jù)報MulticastSocket是一個具有更多功能的DatagramSocket類,它能將多點傳送主機結(jié)合成組。2023/2/283Java網(wǎng)絡程序設計4.3.1創(chuàng)建MulticastSocket對象在Java中,可以用.MulticastSocket類組播數(shù)據(jù)。組播套接字是DatagramSocket的子類,定義如下:publicclassMulticastSocketextendsDatagramSocket構造方法有:(1)publicMulticastSocket():使用本機默認地址、隨機端口來創(chuàng)建一個MulticastSocket對象。2023/2/284Java網(wǎng)絡程序設計4.3.1創(chuàng)建MulticastSocket對象(2)

publicMulticastSocket(intport):

使用本機默認地址、指定端口創(chuàng)建一MulticastSocket對象。(3)

publicMulticastSocket(SocketAddrtessbindaddr):

使用本機指定的IP地址、指定端口來創(chuàng)建一MulticastSocket對象。如果創(chuàng)建僅用于發(fā)送數(shù)據(jù)報的MulticastSocket對象,則使用默認地址、隨機端口即可。但如果創(chuàng)建接收用的MulticastSocket對象,則該對象必須具有指定端口,否則發(fā)送方無法確定發(fā)送數(shù)據(jù)報的目標端口。2023/2/285Java網(wǎng)絡程序設計4.3.2MulticastSocket的常用方法常用的方法如下:

(1)publicvoidjoinGroup(InetAddressaddress)throwsIOException:建立了MulticastSocket對象后,為了發(fā)送或者接收組播包,必須用joinGroup方法加入一個組播組。若加入的不是組播地址將觸發(fā)IOException異常。2023/2/286Java網(wǎng)絡程序設計4.3.2MulticastSocket的常用方法(2)publicvoidleaveGroup(InetAddressaddress)throwsIOException:

如果不想接收組播包了,就調(diào)用leaveGroup方法。程序就發(fā)信息到組播路由器,通知它向此用戶發(fā)送數(shù)據(jù)。若想離開的地址不是組播地址就觸發(fā)IOException異常。2023/2/287Java網(wǎng)絡程序設計4.3.2MulticastSocket的常用方法(3)publicvoidsend(DatagramPacketpacket,byte,ttl)throwsIOExceptin:

發(fā)送組播包的方法與DatagramSocket發(fā)送數(shù)據(jù)相似。其中ttl是生存時間,大小在0~255之間。(4)publicvoidreceive(DatagramPacketp):

與DatagramSocket的接收方法沒有差別。2023/2/288Java網(wǎng)絡程序設計4.3.2MulticastSocket的常用方法(5)publicvoidsetTimeToLive(intttl)throwsIOException:

設置套接字發(fā)出的組播包中的默認ttl數(shù)值。

(6)publicintgetTimeToLive()throwsIOException:

返回ttl數(shù)值。2023/2/289Java網(wǎng)絡程序設計4.3.3組播套接字編程使用組播套接字發(fā)送數(shù)據(jù)的過程:(1)調(diào)用MulticastSocket()創(chuàng)建一個組播套接字。(2)調(diào)用MulticastSocket類的joinGroup()方法加入一個組播組中。(3)創(chuàng)建DatagramPacket數(shù)據(jù)報。(4)調(diào)用MulticastSocket類的send()方法發(fā)送組播包。(5)調(diào)用MulticastSocket類的leaveGroup()方法離開該組播組。(6)關閉組播套接字。發(fā)送一個組播包的代碼如下:2023/2/290Java網(wǎng)絡程序設計4.3.3組播套接字編程InetAddressaddress=InetAddress.getByName(“”);byte[]data=“multicastsocketprogramming”.getBytes();intport=5000;DatagramPacketdatap=newDatagramPacket(data,data.length(),address,port);MulticastSocketmuls=newMulticastSocket();muls.send(datap);2023/2/291Java網(wǎng)絡程序設計4.3.3組播套接字編程使用組播套接字接收數(shù)據(jù)的過程:(1)調(diào)用MulticastSocket(intport)創(chuàng)建一個組播套接字,并綁定到指定端口上。(2)調(diào)用MulticastSocket類的joinGroup()方法加入一個組播組中。(3)創(chuàng)建DatagramPacket數(shù)據(jù)報。(4)調(diào)用MulticastSocket類的receive()方法接收組播數(shù)據(jù)報。(5)調(diào)用MulticastSocket類的leaveGroup()方法離開該組播組。(6)關閉組播套接字MulticastSocket。2023/2/292Java網(wǎng)絡程序設計4.3.4組播套接字編程例子例1:組播竊聽器。.*;importjava.io.*;importjavax.swing.JOptionPane;publicclassMulticastSniffer{publicstaticvoidmain(String[]args){InetAddressgroup=null;intport=0;StringIPName,portName;2023/2/293Java網(wǎng)絡程序設計4.3.4組播套接字編程例子//readtheaddressIPName=JOptionPane.showInputDialog("請輸入組播名或IP地址");portName=JOptionPane.showInputDialog("請輸入端口");try{group=InetAddress.getByName(IPName);port=Integer.parseInt(portName);}//endtrycatch(Exceptionex){System.err.println(“出錯");System.exit(1);}2023/2/294Java網(wǎng)絡程序設計4.3.4組播套接字編程例子MulticastSocketms=null;try{ms=newMulticastSocket(port);ms.joinGroup(group);byte[]buffer=newbyte[8192];while(true){DatagramPacketdp=newDatagramPacket(buffer,buffer.length);ms.receive(dp);Strings=newString(dp.getData());System.out.println(s);}2023/2/295Java網(wǎng)絡程序設計4.3.4組播套接字編程例子}catch(IOExceptionex){System.err.println(ex);}finally{if(ms!=null){try{ms.leaveGroup(group);ms

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論