




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第11單元網(wǎng)絡(luò)編程Java程序設(shè)計基礎(chǔ)教程((慕課版)(第2版))目錄導(dǎo)航11.1網(wǎng)絡(luò)協(xié)議11.3
UDP通信11.2
TCP通信11.4項目實戰(zhàn)11.5單元小結(jié)11.1.1TCP及UDPTCP/IP(TransmissionControlProtocol/InternetProtocol)叫作傳輸控制協(xié)議/互聯(lián)網(wǎng)協(xié)議,又叫作網(wǎng)絡(luò)通信協(xié)議,是互特網(wǎng)中使用的基本通信協(xié)議。該協(xié)議包含兩個保證數(shù)據(jù)完整傳輸?shù)闹匾獏f(xié)議,即TCP和IP,同時包含上百種其他功能的協(xié)議。UDP是UserDatagramProtocol的簡稱,中文名是用戶數(shù)據(jù)報協(xié)議,是OSI(OpenSystemInterconnection,開放系統(tǒng)互連)參考模型中一種無連接的傳輸層協(xié)議,提供面向事務(wù)的簡單不可靠信息傳送服務(wù)。UDP無須三次握手確保連接雙方都已準(zhǔn)備就緒就可以傳輸數(shù)據(jù)。因為免去了三次握手,所以其消耗的服務(wù)器負(fù)載要遠(yuǎn)小于TCP/IP。套接字(Socket)是TCP/IP中的基本概念,負(fù)責(zé)將TCP/IP包發(fā)送到指定的IP地址。它可以看作兩個程序通信連接中的端點。數(shù)據(jù)被寫入套接字中后,該套接字將數(shù)據(jù)發(fā)送到另一個套接字中,使數(shù)據(jù)能夠傳送給其他程序。URL是對可以從互聯(lián)網(wǎng)上得到的資源位置和訪問方法的一種簡潔表示,是互聯(lián)網(wǎng)上資源的標(biāo)準(zhǔn)地址?;ヂ?lián)網(wǎng)上的每個文件都有一個唯一的URL,它包含的信息指出文件的位置以及瀏覽器應(yīng)該怎么處理它。URL由Internet資源類型(http或ftp等)、服務(wù)器地址(host)、端口(port)和資源在服務(wù)器上的位置組成。任務(wù)11-1URL類和URLConnection類的使用文件URLDemo.javapublicclassURLDemo{publicstaticvoidmain(String[]args){try{URLurl=newURL("/index.html");System.out.println("默認(rèn)端口是:"+url.getDefaultPort());//打開一個URLConnection類對象URLConnectionurlConn=url.openConnection();//獲取請求頭Map<String,List<String>>map=urlConn.getHeaderFields();for(Entry<String,List<String>>entry:map.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}System.out.println("content-type:"+urlConn.getContentType());System.out.println("是否獲取用戶緩存:"+urlConn.getDefaultUseCaches());}catch(MalformedURLExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}運行結(jié)果如圖11-1所示。11.1.2IP地址及端口號IP地址具有唯一性,用于唯一標(biāo)識網(wǎng)絡(luò)中的一臺設(shè)備。IPv4
(InternetProtocolVesion4,網(wǎng)際協(xié)議版本4,現(xiàn)行的IP版本)地址由4個小于256的字節(jié)組成,這些字節(jié)通過以“.”連接的32位字符串來表示,如24;IPv6(InternetProtocolVersion6,網(wǎng)際協(xié)議版本6)
則使用8個16位的無符號整數(shù),通過用冒號“∶”隔開表示,例如6dfe:3312:1123:12df:dfdd:123s:fed2:ss4e。Java網(wǎng)絡(luò)包中提供了Inet4Address類和Inet6Address類,分別對應(yīng)IPv4和IPv6地址。由于IP地址是數(shù)字標(biāo)識,難于記憶和書寫,所以在IP地址的基礎(chǔ)上又發(fā)展出一種符號化的地址方案,來代替數(shù)字型的IP地址,每一個符號化的地址與特定的IP地址對應(yīng)。因為符號化的地址有其對應(yīng)的意義和內(nèi)容,所以記憶和書寫都非常方便。這些符號化的地址就是域名,例如人民郵電出版社的域名就是
。但域名不能直接被網(wǎng)絡(luò)設(shè)備所識別,需要域名服務(wù)器(DomainNameServer,DNS)對域名與IP地址做對應(yīng)的轉(zhuǎn)換。計算機端口對應(yīng)的英文是port。硬件中的端口也稱接口;在軟件中,端口一般是指網(wǎng)絡(luò)中面向連接服務(wù)和無連接服務(wù)的通信協(xié)議識別代碼,是一種抽象的軟件結(jié)構(gòu),包括一些數(shù)據(jù)結(jié)構(gòu)和輸入輸出緩沖區(qū)。計算機在通信時需要指定端口,以傳遞信息。端口號可以是0~65535之間的任意一個整數(shù)。任務(wù)11-2IP類的使用文件IPDemo.javapublicclassIPDemo{publicstaticvoidmain(String[]args){try{InetAddressip=InetAddress.getByName("");System.out.println("主機名是:"+ip.getHostName()+",
地址是:"+ip.getHostAddress());System.out.println("地址是否可達(dá):"+ip.isReachable(1000));InetAddress[]ads=InetAddress.getAllByName("");System.out.println("開始獲取當(dāng)前域名對應(yīng)的所有IP地址:");for(InetAddressad:ads){System.out.println(""+ad.getHostName()+":"+ad.getHostAddress());}System.out.println("結(jié)束獲取當(dāng)前域名對應(yīng)的所有IP地址。");System.out.println("當(dāng)前主機的地址是:"+InetAddress.getLocalHost());}catch(UnknownHostExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}運行結(jié)果如圖11-2所示目錄導(dǎo)航11.1網(wǎng)絡(luò)協(xié)議11.3
UDP通信11.2
TCP通信11.4項目實戰(zhàn)11.5單元小結(jié)11.2.1Socket類當(dāng)兩個程序想要通信的時候,可以使用Socket類建立套接字連接,使呼叫的一方成為客戶端,接收的一方成為服務(wù)器端。服務(wù)器端使用的套接字是ServerSocket。Socket類和ServerSocket類使用的IP地址和端口號必須相同,端口號在服務(wù)器端和客戶端必須一致才能通信。③
服務(wù)器端接收到請求,進(jìn)行處理并返回給客戶機處理結(jié)果。④
客戶端接收結(jié)果,進(jìn)行后續(xù)處理。②
客戶端對指定的端口發(fā)起請求。①
服務(wù)器端開啟監(jiān)聽功能,監(jiān)聽指定端口。客戶端/服務(wù)器端對話過程11.2.1Socket類在Java中,Socket類的創(chuàng)建有兩種方式,一種是非阻塞式創(chuàng)建(這種方式可以設(shè)置超時時間):Socketso=newSocket();SocketAddresssaddr=newInetSocketAddress(InetAddress.getByName(""),80);so.connect(saddr,3000);另一種是阻塞式創(chuàng)建:Socketso=newSocket("",80);或者Socketso=newSocket(InetAddress.getByName(""),80);11.2.2ServerSocket類ServerSocket類是服務(wù)器端套接字,用于對指定的端口進(jìn)行監(jiān)聽。當(dāng)監(jiān)聽到請求之后,可以使用accept()方法接收客戶端發(fā)來的消息。該方法是阻塞的,直到有連接響應(yīng),才會返回一個Socket對象。服務(wù)器可以使用該Socket類與客戶端進(jìn)行通信。圖11-3Socket類的通信模型任務(wù)11-3端到端通信文件SocketClientDemo.javapublicclassSocketClientDemo{publicstaticvoidmain(String[]args){try(Socketsocket=newSocket("localhost",8182);InputStreamis=socket.getInputStream();OutputStreamos=socket.getOutputStream()){System.out.println("已經(jīng)連接上服務(wù)器,等待服務(wù)器端返回數(shù)據(jù):");byte[]buf=newbyte[2048];inti=0;StringBuildersb=newStringBuilder();while((i=is.read(buf))!=-1){sb.append(newString(buf,"UTF-8"));}System.out.println("服務(wù)器端返回數(shù)據(jù):"+sb);}catch(IOExceptione){e.printStackTrace();}}}任務(wù)11-3端到端通信文件SocketServerDemo.javapublicclassSocketServerDemo{
publicstaticvoidmain(String[]args)throwsIOException{try(ServerSocketss=newServerSocket(8182)){while(true){try(Socketso=ss.accept();OutputStreamos=so.getOutputStream();PrintWriterpw=newPrintWriter(os);InputStreamis=so.getInputStream()){System.out.println("客戶端地址【:"+so.getInetAddress()+",端口號:"+so.getPort()+"】已經(jīng)連接到服務(wù)器!");pw.write("Hello,"+so.getInetAddress()+",非常感謝您的本次連接。");pw.write("連接成功!");pw.flush();System.out.println("服務(wù)器端數(shù)據(jù)返回成功!開始后續(xù)數(shù)據(jù)的交流步驟!");}}}}}運行結(jié)果如圖11-4所示。目錄導(dǎo)航11.1網(wǎng)絡(luò)協(xié)議11.3
UDP通信11.2
TCP通信11.4項目實戰(zhàn)11.5單元小結(jié)11.3.1DatagramPacket類與UDP通信相關(guān)的處理類是DatagramPacket類,該類位于
包下。該類在接收方和發(fā)送方創(chuàng)建的對象是不同的,當(dāng)發(fā)送的時候,發(fā)送方不僅要將需要發(fā)送的數(shù)據(jù)告訴DatagramPacket對象,還需要將數(shù)據(jù)要發(fā)送的地址和端口號告訴DatagramPacket對象;接收方則只需聲明要獲取的數(shù)據(jù)即可。方法功能描述DatagramPacket(byte[]buf,intlength)創(chuàng)建時指定封裝的字節(jié)數(shù)據(jù)和長度大小,用于數(shù)據(jù)接收方DatagramPacket(byte[]buf,intoffset,int
length)創(chuàng)建時指定封裝的字節(jié)數(shù)據(jù)、數(shù)據(jù)的偏移量和讀取長度,用于數(shù)據(jù)接收方DatagramPacket(byte[]buf,intlength,
InetAddressaddr,intprot)創(chuàng)建時指定封裝的字節(jié)數(shù)據(jù)、封裝數(shù)據(jù)的大小、指定數(shù)據(jù)包的IP地址和端口號,用于數(shù)據(jù)發(fā)送方DatagramPacket(byte[]buf,intoffset,int
length,InetAddressaddr,intprot)創(chuàng)建時指定封裝的字節(jié)數(shù)據(jù)、數(shù)據(jù)的偏移量、封裝數(shù)據(jù)的大小、指定數(shù)據(jù)包的IP地址和端口號,用于數(shù)據(jù)發(fā)送方InetAddressgetAddress()返回DatagramPacket對象的IP地址。如果是發(fā)送方,則返回接收方的IP地址;如果是接收方,則返回發(fā)送方的IP地址intgetOffset()返回要發(fā)送數(shù)據(jù)的偏移量或要接收數(shù)據(jù)的偏移量intgetPort()同getAddress()方法類似,用于返回端口號voidsetPort()設(shè)置發(fā)送數(shù)據(jù)包的遠(yuǎn)程主機端口號byte[]getData()用于返回將要發(fā)送或者接收的數(shù)據(jù),發(fā)送方返回發(fā)送數(shù)據(jù),接收方返回接收數(shù)據(jù)byte[]setData(byte[]buf)設(shè)置數(shù)據(jù)包的數(shù)據(jù)緩沖區(qū)intgetLength()返回將要發(fā)送或接收數(shù)據(jù)的長度表11-1DatagramPacket類中常用的方法11.3.2DatagramSocket類DatagramSocket類專用于發(fā)送和接收使用DatagramPacket類打包的數(shù)據(jù)。兩者分工明確,前者負(fù)責(zé)接收和發(fā)送經(jīng)過后者打包的數(shù)據(jù),后者則專門負(fù)責(zé)數(shù)據(jù)的打包工作。表11-2DatagramSocket類中常用的方法方法功能描述DatagramSocket(intport)構(gòu)造數(shù)據(jù)包套接字并將其綁定到本地主機上的指定端口DatagramSocket(intport,InetAddressladdr)創(chuàng)建一個數(shù)據(jù)包套接字,綁定到指定的本地地址DatagramSocket(SocketAddressbindaddr)創(chuàng)建一個數(shù)據(jù)包套接字,綁定到指定的本地套接字地址voidconnect(InetAddressaddress,intport)將套接字連接到其遠(yuǎn)程地址voiddisconnect()斷開連接intgetReceiveBufferSize()獲取DatagramSocket類的SO_RCVBUF參數(shù)的值,即平臺在DatagramSocket類上輸入的緩沖區(qū)大小intgetSendBufferSize()獲取DatagramSocket類的SO_SNDBUF參數(shù)的值,即平臺在DatagramSocket類上輸出的緩沖區(qū)大小intgetSoTimeout()檢索SO_TIMEOUT的設(shè)置voidsetSoTimeout(inttimeout)以指定的超時時間(以毫秒為單位)啟用/禁用SO_TIMEOUTvoidreceive(DatagramPacketp)從指定套接字接收數(shù)據(jù)包voidsend(DatagramPacketp)從指定套接字發(fā)送數(shù)據(jù)包任務(wù)11-4UDP通信模型文件UDPSendDemo.javapackagecom.lw.chapter11;importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;import.SocketException;import.UnknownHostException;publicclassUDPSendDemo{publicstaticvoidmain(String[]args){//使用字符串創(chuàng)建一個數(shù)據(jù)字節(jié)數(shù)組byte[]b="你好,服務(wù)器,這是第一個數(shù)據(jù)包".getBytes();//聲明發(fā)送的DatagramSocket對象DatagramSocketds=null;try{//創(chuàng)建DatagramPacket對象,并初始化數(shù)據(jù)、長度、目標(biāo)地址和端口號參數(shù)DatagramPacketdp=newDatagramPacket(b,b.length,InetAddress.getByName("localhost"),9900);//創(chuàng)建DatagramSocket對象ds=newDatagramSocket(9901);//發(fā)送數(shù)據(jù)ds.send(dp);任務(wù)11-4UDP通信模型//輸出信息System.out.println("發(fā)送信息:");System.out.println("數(shù)據(jù):"+newString(dp.getData(),"UTF-8")+";發(fā)送到:"+dp.getAddress().getHostAddress()+";
端口號:"+dp.getPort());}catch(UnknownHostExceptione){e.printStackTrace();}catch(SocketExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{//關(guān)閉DatagramSocket對象if(null!=ds){ds.close();}}}}文件UDPRecvDemo.javapackagecom.lw.chapter11;importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.SocketException;任務(wù)11-4UDP通信模型publicclassUDPRecvDemo{publicstaticvoidmain(String[]args){//創(chuàng)建一個字節(jié)數(shù)組,用于存放數(shù)據(jù)byte[]b=newbyte[2048];//創(chuàng)建一個DatagramPacket對象DatagramPacketdp=newDatagramPacket(b,2048);//聲明DatagramSocket對象DatagramSocketds=null;try{//初始化DatagramSocket對象ds=newDatagramSocket(9900);//接收數(shù)據(jù)ds.receive(dp);//輸出信息System.out.println("接收數(shù)據(jù):");System.out.println("數(shù)據(jù):"+newString(dp.getData(),"UTF-8").trim()+";
來源:"+dp.getAddress().getHostAddress()+";
端口號:"+dp.getPort());}catch(SocketExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{if(null!=ds){ds.close();}//關(guān)閉DatagramSocket對象}}}運行結(jié)果分別如圖11-5和圖11-6所示。圖11-5發(fā)送信息的運行結(jié)果圖11-6接收數(shù)據(jù)的運行結(jié)果目錄導(dǎo)航11.1網(wǎng)絡(luò)協(xié)議11.3
UDP通信11.2
TCP通信11.4項目實戰(zhàn)11.5單元小結(jié)項目11-1設(shè)計通信程序QQ和微信現(xiàn)在已經(jīng)成了很多人無法離開的通信交流軟件,它們方便了人們的交流和溝通。通過對Java的學(xué)習(xí),再結(jié)合多線程和UDP通信,聊天軟件的神秘面紗就可以揭開了,聊天軟件的核心也就非常好理解了。本項目結(jié)合已經(jīng)學(xué)習(xí)的內(nèi)容模仿編寫一個聊天室,實現(xiàn)聊天室消息的發(fā)送和接收功能,并將接收的數(shù)據(jù)顯示出來。
程序運行結(jié)果如圖所示。項目11-1設(shè)計通信程序文件ChatClientDemo.javapackagecom.lw.chapter11;importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;import.SocketException;import.UnknownHostException;importjava.util.Scanner;publicclassChatClientDemo{publicstaticvoidmain(String[]args){@SuppressWarnings("resource")Scannerscan=newScanner(System.in);//用于獲取客戶端監(jiān)聽的端口和發(fā)送的數(shù)據(jù)System.out.println("請輸入監(jiān)聽端口:");StringportStr=scan.nextLine();//獲取用戶監(jiān)聽端口intport=Integer.parseInt(portStr);//轉(zhuǎn)化成int類型的數(shù)值//定義一個線程對象,異步接收服務(wù)器端的廣播數(shù)據(jù)Runnabler=newRunnable(){@SuppressWarnings("resource")@Overridepublicvoidrun(){byte[]buf=newbyte[1024];//字節(jié)數(shù)據(jù)對象//初始化DatagramPacket對象DatagramPacketdp=newDatagramPacket(buf,buf.length);DatagramSocketds=null;try{ds=newDatagramSocket(port);//創(chuàng)建DatagramSocket對象}catch(SocketExceptione1){e1.printStackTrace();}//循環(huán)監(jiān)聽數(shù)據(jù)while(true){try{//監(jiān)聽并接收數(shù)據(jù)ds.receive(dp);//輸出數(shù)據(jù)System.out.println(newString(dp.getData(),"UTF-8"));}catch(SocketExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}};項目11-1設(shè)計通信程序//啟動異步線程進(jìn)行數(shù)據(jù)監(jiān)聽Threadt=newThread(r);t.start();
//通過主線程進(jìn)行數(shù)據(jù)發(fā)送DatagramSocketds=null;try{ds=newDatagramSocket();while(true){//獲取用戶輸入數(shù)據(jù)Stringline=scan.nextLine();//如果是非空數(shù)據(jù),則發(fā)送消息,否則獲取下一行的輸入if(null!=line){//組裝數(shù)據(jù),數(shù)據(jù)格式是port:messageline=port+":"+line;//創(chuàng)建數(shù)據(jù)包DatagramPacketdp=newDatagramPacket(line.getBytes(),line.getBytes().length,InetAddress.getByName("localhost"),9901);//發(fā)送數(shù)據(jù)包try{ds.send(dp);}catch(IOExceptione){e.printStackTrace();}}else{continue;}}}catch(SocketExceptione){e.printStackTrace();}catch(UnknownHostExceptione1){e1.printStackTrace();}finally{//關(guān)閉數(shù)據(jù)流if(null!=ds){ds.close();}}}}項目11-1設(shè)計通信程序服務(wù)器端實現(xiàn)代碼如下。packagecom.lw.chapter11;importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;import.SocketException;importjava.util.HashSet;importjava.util.Set;publicclassChatServerDemo{publicstaticvoidmain(String[]args){//使用Set集合保存注冊用戶的信息Set<String>registerSet=newHashSet<>();byte[]buf=newbyte[1024];//初始化數(shù)據(jù)數(shù)組//不間斷監(jiān)聽DatagramSocketds=null;try{ds=newDatagramSocket(9901);文件ChatServerDemo.javawhile(true){//初始化DatagramPacket對象DatagramPacketdp=newDatagramPacket(buf,buf.length);//接收數(shù)據(jù)ds.receive(dp);//處理客戶端數(shù)據(jù)Stringinfo=newString(dp.getData(),"UTF-8");//客戶端數(shù)據(jù)StringportStr=info.substring(0,info.indexOf(":"));//截取端口號StringhostName=dp.getAddress().getHostAddress();//組裝host地址信息Stringhost=hostName+"-"+portStr
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 餐飲業(yè)多人合伙創(chuàng)業(yè)合作協(xié)議范本
- 文化創(chuàng)意產(chǎn)業(yè)園區(qū)商位租賃與創(chuàng)意成果轉(zhuǎn)化合同
- 車輛購置稅損失賠償合同
- 精裝住宅樓裝修工程合同
- 專業(yè)市場場地使用權(quán)轉(zhuǎn)讓及設(shè)備租賃協(xié)議
- 大數(shù)據(jù)分析支持下的物流采購合同
- 護(hù)理急救案例分享
- 車輛掛靠免賠責(zé)任協(xié)議范本
- 節(jié)假日車輛租賃合同及應(yīng)急預(yù)案
- 車輛抵押貸款風(fēng)險控制服務(wù)協(xié)議
- 理論聯(lián)系實際談一談如何維護(hù)政治安全?參考答案1
- 2025屆安徽省合肥市A10聯(lián)盟高三下學(xué)期最后一卷歷史試題(B卷)
- 2025屆廣東省東莞中學(xué)七年級數(shù)學(xué)第二學(xué)期期末聯(lián)考試題含解析
- 2024吉林省農(nóng)村信用社聯(lián)合社招聘筆試歷年典型考題及考點剖析附帶答案詳解
- 人工智能設(shè)計倫理知到智慧樹章節(jié)測試課后答案2024年秋浙江大學(xué)
- 2024年福建高考真題化學(xué)試題(解析版)
- 生物醫(yī)學(xué)電子學(xué)智慧樹知到期末考試答案章節(jié)答案2024年天津大學(xué)
- 就遠(yuǎn)原則和就近原則
- 工程變更申請單ECR
- 智能除濕裝置施工方案
- SHD01-120塑料門窗單點任意角焊接機
評論
0/150
提交評論