Java語(yǔ)言程序設(shè)計(jì) 課件 第19章 Java網(wǎng)絡(luò)編程_第1頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第19章 Java網(wǎng)絡(luò)編程_第2頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第19章 Java網(wǎng)絡(luò)編程_第3頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第19章 Java網(wǎng)絡(luò)編程_第4頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第19章 Java網(wǎng)絡(luò)編程_第5頁(yè)
已閱讀5頁(yè),還剩59頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Java語(yǔ)言程序設(shè)計(jì)第19章Java網(wǎng)絡(luò)編程

1網(wǎng)絡(luò)概述23主要內(nèi)容

Java語(yǔ)言程序設(shè)計(jì)(第4版)清華大學(xué)出版社2023基于TCP的通信基于UDP的通信45基于HTTP編程案例:訪問(wèn)Web應(yīng)用程序Java語(yǔ)言程序設(shè)計(jì)19.1網(wǎng)絡(luò)概述Java語(yǔ)言作為最流行的網(wǎng)絡(luò)編程語(yǔ)言,提供了強(qiáng)大的網(wǎng)絡(luò)編程功能。使用Java語(yǔ)言可以編寫(xiě)底層的網(wǎng)絡(luò)通信程序,這是通過(guò)包中提供的InetAddress類(lèi)、Socket類(lèi)、ServerSocket類(lèi)、URL類(lèi)以及URLConnection等類(lèi)實(shí)現(xiàn)的。19.1.1網(wǎng)絡(luò)分層與協(xié)議最常用的是適用于Internet的TCP/IP四層模型,包括主機(jī)網(wǎng)絡(luò)層、網(wǎng)際層、傳輸層和應(yīng)用層。應(yīng)用層(HTTP,SMTP,F(xiàn)TP)傳輸層(TCP,UDP)網(wǎng)際層(IP)主機(jī)網(wǎng)絡(luò)層協(xié)議(protocol)是定義計(jì)算機(jī)之間如何通信的一組規(guī)則。網(wǎng)際層最重要的協(xié)議是IP,它是基于TCP/IP網(wǎng)絡(luò)協(xié)議的核心協(xié)議傳輸控制協(xié)議TCP(TransmissionControlProtocol)和用戶(hù)數(shù)據(jù)報(bào)協(xié)議UDP(UserDatagramProtocol)。TCP是面向連接的協(xié)議,是可靠的協(xié)議。UDP是面向無(wú)連接的協(xié)議,是不可靠協(xié)議。用于Web的HTTP,還有用于電子郵件的SMTP、POP3,用于文件傳輸?shù)腇TP。發(fā)出連接請(qǐng)求的計(jì)算機(jī)稱(chēng)為客戶(hù)端,提供服務(wù)的計(jì)算機(jī)稱(chēng)為服務(wù)器。在客戶(hù)端發(fā)出連接請(qǐng)求時(shí),服務(wù)器必須正在等待客戶(hù)端的請(qǐng)求。19.1.2客戶(hù)/服務(wù)器結(jié)構(gòu)Web是Internet上最流行的客戶(hù)/服務(wù)器(C/S)結(jié)構(gòu)。Web服務(wù)器(如Apache)響應(yīng)Web客戶(hù)端(如Firefox)的請(qǐng)求。數(shù)據(jù)被存儲(chǔ)在Web服務(wù)器上,在被請(qǐng)求時(shí)發(fā)送給客戶(hù)端。連接到Internet上的計(jì)算機(jī)使用IP地址或域名來(lái)唯一標(biāo)識(shí)。一般來(lái)說(shuō),IP地址是由4個(gè)用點(diǎn)號(hào)分隔開(kāi)的0~255之間的十進(jìn)制數(shù)組成,如36。19.1.3IP地址和域名域名系統(tǒng)(DomainNameSystem),用來(lái)將人類(lèi)易于記憶的主機(jī)名()轉(zhuǎn)換為數(shù)字Internet地址(4)。地址是一個(gè)比較特殊的IP地址,它被保留用作本機(jī)回路地址(loopback),該地址對(duì)應(yīng)的主機(jī)名是localhost。當(dāng)程序訪問(wèn)網(wǎng)絡(luò)時(shí),需要同時(shí)處理數(shù)字地址和相應(yīng)的主機(jī)名。這些操作的方法由.InetAddress類(lèi)提供。19.1.3IP地址和域名InetAddress類(lèi)沒(méi)有提供構(gòu)造方法,要得到一個(gè)InetAddress類(lèi)對(duì)象,需要使用該類(lèi)的靜態(tài)方法。staticInetAddressgetByName(Stringhost)staticInetAddressgetLocalHost()staticInetAddress[]getAllByName(Stringhost)下面是InetAddress類(lèi)的其他方法:StringgetHostName()StringgetHostAddress()byte[]getAddress()19.1.3IP地址和域名包中還提供了Inet4Address類(lèi)和Inet6Address,它們分別表示IPv4和IPv6地址,并提供了相應(yīng)的方法對(duì)它們操作。Stringhostname="";try{InetAddressaddress=InetAddress.getByName(hostname);System.out.println(address);System.out.println("主機(jī)名:"+address.getHostName());System.out.println("IP地址:"+address.getHostAddress());}catch(UnknownHostExceptionex){System.out.println("給定的主機(jī)不存在");}程序19.1SearchIP.java實(shí)現(xiàn)網(wǎng)絡(luò)通信必須將兩臺(tái)機(jī)器連接起來(lái)建立一個(gè)雙向通信鏈路,這個(gè)雙向通信鏈路的每一端稱(chēng)為一個(gè)套接字(socket)。19.1.4端口號(hào)與套接字通常使用一個(gè)整數(shù)來(lái)標(biāo)識(shí)該機(jī)器上的某個(gè)服務(wù),這個(gè)整數(shù)就是端口號(hào)(port)。端口號(hào)是用16位整數(shù)標(biāo)識(shí),共有65536個(gè)端口號(hào)。端口號(hào)分為兩類(lèi)。一類(lèi)是由因特網(wǎng)名字和號(hào)碼指派公司ICANN分配給一些常用的應(yīng)用層程序固定使用的熟知端口(well-knownport),其值范圍為0~1023。例如,HTTP服務(wù)的端口號(hào)為80,F(xiàn)TP服務(wù)的端口號(hào)為21。19.1.4端口號(hào)與套接字另一類(lèi)端口為一般端口,用來(lái)隨時(shí)分配給請(qǐng)求通信的客戶(hù)進(jìn)程。為了在通信時(shí)不致發(fā)生混亂,必須把端口號(hào)和主機(jī)的IP地址結(jié)合在一起使用。一個(gè)TCP連接由它的兩個(gè)端點(diǎn)來(lái)標(biāo)識(shí),而每一個(gè)端點(diǎn)又是由IP地址和端口號(hào)決定的。TCP連接的端點(diǎn)稱(chēng)為套接字,IP地址和端口號(hào)一起構(gòu)成套接字,如圖所示。19.1.4端口號(hào)與套接字運(yùn)行在一臺(tái)特定機(jī)器上的某個(gè)服務(wù)器(如HTTP服務(wù)器)都有一個(gè)套接字綁定到該服務(wù)器上。服務(wù)器只是等待、監(jiān)聽(tīng)客戶(hù)的連接請(qǐng)求。

在客戶(hù)端,客戶(hù)機(jī)需要知道服務(wù)器的主機(jī)名和端口號(hào)。為了建立連接請(qǐng)求,客戶(hù)機(jī)試圖與服務(wù)器機(jī)上的指定端口號(hào)上的服務(wù)連接。服務(wù)器將接受連接請(qǐng)求。一旦接受了請(qǐng)求,服務(wù)器將創(chuàng)建一個(gè)新的綁定到另一個(gè)端口號(hào)的套接字.19.1.4端口號(hào)與套接字6.1.1課堂討論及訓(xùn)練Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486編寫(xiě)一個(gè)JavaFX圖形界面程序,通過(guò)文本框輸入一個(gè)主機(jī)名,利用該主機(jī)名找到該主機(jī)的IP地址并通過(guò)標(biāo)簽顯示出來(lái)。下圖是當(dāng)輸入主機(jī)名后單擊“查找”按鈕顯示的IP地址。Java語(yǔ)言程序設(shè)計(jì)19.2基于TCP的通信編寫(xiě)網(wǎng)絡(luò)程序時(shí),有兩種通信可供選擇:基于TCP的通信和基于UDP的通信。19.2.1基于TCP和UDP通信的對(duì)比基于TCP的通信使用TCP協(xié)議,該協(xié)議是面向連接的協(xié)議。使用這種協(xié)議要求發(fā)送方和接收方都要建立套接字,一旦兩個(gè)套接字建立起來(lái),它們就可以進(jìn)行雙向通信,雙方都可以發(fā)送和接收數(shù)據(jù)?;赨DP的通信使用UDP協(xié)議,該協(xié)議是一種無(wú)連接的協(xié)議。使用這種協(xié)議通信,每個(gè)數(shù)據(jù)報(bào)都是一個(gè)獨(dú)立的信息單元,它包括完整的目的地址,數(shù)據(jù)報(bào)在網(wǎng)絡(luò)上以任何可能的路徑傳往目的地,因此數(shù)據(jù)能否到達(dá)目的地、到達(dá)的時(shí)間以及內(nèi)容的正確性都不能保證,該協(xié)議提供的是不可靠的服務(wù)。(1)TCP是一個(gè)面向連接的協(xié)議,在通信之前必須建立雙方的連接,因此在TCP中多了一個(gè)建立連接的時(shí)間。使用UDP時(shí),每個(gè)數(shù)據(jù)報(bào)都給出了完整的地址信息,因此無(wú)需建立發(fā)送方和接收方的連接。19.2.1基于TCP和UDP通信的對(duì)比(2)使用TCP沒(méi)有數(shù)據(jù)大小的限制,一旦建立起連接,就可以傳輸大量的數(shù)據(jù)。使用UDP傳輸數(shù)據(jù)時(shí)是有大小限制的,每個(gè)數(shù)據(jù)報(bào)必須不大于64KB。(3)TCP是可靠的協(xié)議,它確保接收方正確地獲取發(fā)送方所發(fā)送的數(shù)據(jù)。UDP是不可靠的協(xié)議,發(fā)送方發(fā)送的數(shù)據(jù)不一定以相同的次序到達(dá)接收方。19.2.1基于TCP和UDP通信的對(duì)比(4)TCP使用較廣泛,如TELNET遠(yuǎn)程登錄、FTP文件傳輸都需要不定長(zhǎng)度的數(shù)據(jù)可靠地傳輸,因此需要使用TCP協(xié)議。相比之下UDP比較簡(jiǎn)單,因此常用于局域網(wǎng)分散系統(tǒng)中的客戶(hù)/服務(wù)器應(yīng)用程序。為了實(shí)現(xiàn)基于TCP的通信,在包中提供了兩個(gè)類(lèi):ServerSocket和Socket。它們分別實(shí)現(xiàn)連接的服務(wù)器端和客戶(hù)端的套接字。19.2.2ServerSocket類(lèi)和Socket類(lèi)ServerSocket類(lèi)用在服務(wù)器端??蛻?hù)與服務(wù)器通信,客戶(hù)向服務(wù)器提出請(qǐng)求,服務(wù)器監(jiān)聽(tīng)請(qǐng)求,一旦監(jiān)聽(tīng)到客戶(hù)請(qǐng)求,服務(wù)器要建立一個(gè)套接字。ServerSocket類(lèi)的構(gòu)造方法如下。ServerSocket(intport):創(chuàng)建綁定到指定端口port上的服務(wù)器套接字。注意,因?yàn)橛行┒丝谔?hào)已被特殊的服務(wù)占用,所以應(yīng)該選擇大于1023的端口號(hào)。ServerSocket(intport,intbacklog):參數(shù)backlog指定最大的隊(duì)列數(shù),即服務(wù)器所能支持的最大連接數(shù)。ServerSocket類(lèi)提供的主要方法:publicSocketaccept():調(diào)用該方法將阻塞當(dāng)前系統(tǒng)服務(wù)線程,直到有客戶(hù)連接。當(dāng)有客戶(hù)連接時(shí),方法返回一個(gè)Socket對(duì)象。正是通過(guò)該Socket對(duì)象,服務(wù)器才可與客戶(hù)通信。publicvoidclose():關(guān)閉ServerSocket對(duì)象。19.2.2ServerSocket類(lèi)和Socket類(lèi)Socket類(lèi)是套接字類(lèi),它既用在服務(wù)器端,也用在客戶(hù)端??蛻?hù)和服務(wù)器之間就是用Socket對(duì)象通信的。Socket類(lèi)的最常用構(gòu)造方法如下。19.2.2ServerSocket類(lèi)和Socket類(lèi)publicSocket(Stringhost,intport):創(chuàng)建一個(gè)套接字對(duì)象并將其連接到服務(wù)器主機(jī)的指定端口上。host為服務(wù)器主機(jī)名,port為端口號(hào)。publicSocket(InetAddressaddress,intport):創(chuàng)建一個(gè)套接字對(duì)象并將其連接到指定IP地址的指定端口上。address為服務(wù)器主機(jī)的IP地址,port為端口號(hào)。Socket類(lèi)提供的主要方法有:publicInputStreangetInputStream():獲得套接字上綁定的數(shù)據(jù)輸入流。publicOutputStreamgetOutputStream():獲得套接字上綁定的數(shù)據(jù)輸出流。publicInetAddressgetInetAddress():返回該套接字所連接的IP地址。publicintgetPort():返回該套接字所連接的遠(yuǎn)程端口號(hào)。publicsynchronizedvoidclose()throwsIOException:關(guān)閉套接字對(duì)象。19.2.2ServerSocket類(lèi)和Socket類(lèi)(1)雙方創(chuàng)建套接字對(duì)象。(2)創(chuàng)建連接到套接字的輸入/輸出流。(3)按照一定協(xié)議對(duì)套接字進(jìn)行讀寫(xiě)操作。(4)關(guān)閉套接字對(duì)象。套接字通信基本步驟服務(wù)器端程序首先在端口號(hào)8080上創(chuàng)建一個(gè)ServerSocket對(duì)象,然后調(diào)用它的accept()方法等待客戶(hù)的連接。如果客戶(hù)端程序請(qǐng)求連接該服務(wù)器,accept()方法將返回一個(gè)Socket對(duì)象,通過(guò)socket對(duì)象的getInputStream()方法和getOutputStream()方法分別獲得輸入流和輸出流對(duì)象,使用它們與客戶(hù)端通信。程序中使用InputStreamReader類(lèi)將字節(jié)輸入流轉(zhuǎn)換成字符輸入流。19.2.3簡(jiǎn)單的TCP通信的例子TCPServer.java是服務(wù)器端程序。try(varserver=newServerSocket(8080);varsocket=server.accept();varis=newBufferedReader(newInputStreamReader(socket.getInputStream()));varos=newPrintWriter(socket.getOutputStream());varinput=newScanner(System.in);){System.out.println("客戶(hù)端:"+is.readLine());//顯示從客戶(hù)端讀的數(shù)據(jù)System.out.print("服務(wù)器端:");程序19.2TCPServer.javavarline=input.nextLine();//從鍵盤(pán)讀一行數(shù)據(jù)while(!line.equals("bye")){os.println(line);//將數(shù)據(jù)發(fā)送到客戶(hù)端os.flush();System.out.println("客戶(hù)端:"+is.readLine());//顯示從客戶(hù)端讀的數(shù)據(jù)System.out.print("服務(wù)器端:");line=input.nextLine();//從鍵盤(pán)讀一行數(shù)據(jù)}}catch(Exceptione){System.out.println("發(fā)生異常:"+e);}客戶(hù)程序首先建立一個(gè)Socket對(duì)象,這里需要指定服務(wù)器主機(jī)名和端口號(hào)。如果連接本地主機(jī),可使用locahost主機(jī)名或地址。端口號(hào)是服務(wù)器使用的端口號(hào)8080。本例中服務(wù)器程序和客戶(hù)程序運(yùn)行在同一臺(tái)機(jī)器上,如果客戶(hù)程序和服務(wù)器程序不在一臺(tái)計(jì)算機(jī)上,客戶(hù)程序創(chuàng)建Socket時(shí)應(yīng)該指定主機(jī)名或IP地址。19.2.3簡(jiǎn)單的TCP通信的例子TCPClient.java是客戶(hù)端程序。try(varsocket=newSocket("",8080);varis=newBufferedReader(newInputStreamReader(socket.getInputStream()));varos=newPrintWriter(socket.getOutputStream());varinput=newScanner(System.in);){System.out.print("客戶(hù)端:");varline=input.nextLine();//從鍵盤(pán)讀一行數(shù)據(jù)程序19.3TCPClient.javawhile(!line.equals("bye")){os.println(line);//將數(shù)據(jù)發(fā)送到服務(wù)器os.flush();//輸出從服務(wù)器端讀的一行數(shù)據(jù)System.out.println("服務(wù)器端:"+is.readLine());System.out.print("客戶(hù)端:");line=input.nextLine();//從鍵盤(pán)讀一行數(shù)據(jù)}}catch(Exceptione){System.out.println("發(fā)生異常:"+e);}要測(cè)試該程序,啟動(dòng)兩個(gè)命令行窗口并且先運(yùn)行服務(wù)器程序,后運(yùn)行客戶(hù)程序,客戶(hù)程序先向服務(wù)器發(fā)送消息。該程序的運(yùn)行效果如圖19-6和19-7所示。19.2.3簡(jiǎn)單的TCP通信的例子6.1.1課堂討論及訓(xùn)練Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486編寫(xiě)程序,使用ServerSocket類(lèi)和Socket類(lèi)編寫(xiě)一個(gè)GUI程序,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的聊天程序,界面如圖所示。Java語(yǔ)言程序設(shè)計(jì)19.3基于UDP的通信用UDP編寫(xiě)客戶(hù)/服務(wù)器程序時(shí),無(wú)論是客戶(hù)方還是服務(wù)器方,首先都要建立一個(gè)DatagramSocket對(duì)象用來(lái)接收或發(fā)送數(shù)據(jù)報(bào),然后使用DatagramPacket類(lèi)對(duì)象作為傳輸數(shù)據(jù)的載體。19.3.1DatagramSocket類(lèi)和DatagramPacket類(lèi)1.DatagramSocket類(lèi)DatagramSocket類(lèi)用于在通信的兩端建立數(shù)據(jù)報(bào)套接字,它的構(gòu)造方法有:publicDatagramSocket(intport)throwsSocketException:創(chuàng)建數(shù)據(jù)報(bào)套接字,并將它綁定在本地主機(jī)指定的端口上。publicDatagramSocket()throwsSocketException:創(chuàng)建數(shù)據(jù)報(bào)套接字,并將它綁定在本地主機(jī)一個(gè)可用的端口上。DatagramSocket類(lèi)的常用方法有:publicvoidreceive(DatagramPacketp)throwsIOException:接收一個(gè)報(bào)文,參數(shù)p用來(lái)保存接收的報(bào)文。publicvoidsend(DatagramPacketp)throwsIOException:發(fā)送一個(gè)報(bào)文,參數(shù)p保存了要發(fā)送的報(bào)文。報(bào)文包括數(shù)據(jù)、接收者的IP地址及其端口。publicInetAddressgetInetAddress():返回該套接字連接的IP地址,如果套接字沒(méi)有連接返回null。publicInetAddressgetLocalAddress():返回套接字綁定的本地IP地址。19.3.1DatagramSocket類(lèi)和DatagramPacket類(lèi)2.DatagramPacket類(lèi)DatagramPacket類(lèi)用于創(chuàng)建一個(gè)數(shù)據(jù)報(bào),它的構(gòu)造方法有:publicDatagramPacket(byte[]buf,intlength):該構(gòu)造方法創(chuàng)建的對(duì)象用于接收數(shù)據(jù)報(bào)。參數(shù)buf為數(shù)據(jù)報(bào)文緩沖區(qū),length為緩沖區(qū)的長(zhǎng)度。publicDatagramPacket(byte[]buf,intlength,InetAddressaddress,intport):該構(gòu)造方法創(chuàng)建的對(duì)象用于發(fā)送數(shù)據(jù)報(bào)。參數(shù)buf為數(shù)據(jù)報(bào)文緩沖區(qū),length為緩沖區(qū)的長(zhǎng)度,address為接收方的地址,port為接收方數(shù)據(jù)報(bào)套接字綁定的端口號(hào)。19.3.1DatagramSocket類(lèi)和DatagramPacket類(lèi)在接收數(shù)據(jù)之前,應(yīng)該創(chuàng)建一個(gè)DatagramPacket對(duì)象,給出接收數(shù)據(jù)的緩沖區(qū)及長(zhǎng)度。然后調(diào)用DatagramSocket的receive()方法等待數(shù)據(jù)報(bào)的到來(lái),receive()方法將一直等待,直到有一個(gè)數(shù)據(jù)報(bào)到來(lái)。19.3.1DatagramSocket類(lèi)和DatagramPacket類(lèi)byte[]buf=newbyte[1024];DatagramPacketpacket=newDatagramPacket(buf,1024);socket.receive(packet);//接收數(shù)據(jù)在發(fā)送數(shù)據(jù)前,也要生成一個(gè)DatagramPacket對(duì)象,在給出發(fā)送方的數(shù)據(jù)緩沖區(qū)及長(zhǎng)度的同時(shí),還要給出完整的目標(biāo)地址,包括IP地址和端口號(hào)。發(fā)送數(shù)據(jù)通過(guò)DatagramSocket的send()方法實(shí)現(xiàn)的,send()方法根據(jù)目的地址選擇路徑。19.3.1DatagramSocket類(lèi)和DatagramPacket類(lèi)DatagramPacketpacket=newDatagramPacket(msg,send.length(),clientIP,clientPort);socket.send(packet);//發(fā)送數(shù)據(jù)下面的實(shí)例通過(guò)UDP實(shí)現(xiàn)通信。該實(shí)例實(shí)現(xiàn)的功能是客戶(hù)端向服務(wù)器端發(fā)送一個(gè)字符串,服務(wù)器端接收該字符串,然后將其轉(zhuǎn)換成大寫(xiě)字母,再發(fā)送回客戶(hù)端。UDPServer.java是服務(wù)器端程序,UDPClient.java是客戶(hù)端程序。19.3.2簡(jiǎn)單的UDP通信例子 byte[]buf=newbyte[1024]; try{ varsocket=newDatagramSocket(8888); System.out.println("服務(wù)器等待..."); while(true){ //用于接收數(shù)據(jù)的數(shù)據(jù)報(bào) varpacket=newDatagramPacket(buf,1024); socket.receive(packet); vardata=newString(buf,0,packet.getLength()); if(data.toLowerCase().equals("bye")) break; System.out.println("客戶(hù)數(shù)據(jù):"+data);程序19.4UDPServer.java varsend=data.toUpperCase(); varclientIP=packet.getAddress();//返回客戶(hù)端的IP地址 intclientPort=packet.getPort();//返回客戶(hù)端的端口號(hào) byte[]msg=send.getBytes(); //用于發(fā)送數(shù)據(jù)的數(shù)據(jù)報(bào) varsendPacket=newDatagramPacket( msg,send.length(),clientIP,clientPort); socket.send(sendPacket); } socket.close(); System.out.println("Serverisclosed."); }catch(Exceptione){ e.printStackTrace(); }程序在端口號(hào)8888上創(chuàng)建一個(gè)數(shù)據(jù)報(bào)套接字socket,然后創(chuàng)建一個(gè)接收數(shù)據(jù)的數(shù)據(jù)報(bào)對(duì)象packet,并調(diào)用套接字的receive()方法接收數(shù)據(jù)報(bào)。在接收到數(shù)據(jù)報(bào)后,將其轉(zhuǎn)換成字符串并轉(zhuǎn)換成大寫(xiě)字母。接下來(lái)創(chuàng)建一個(gè)發(fā)送數(shù)據(jù)的數(shù)據(jù)報(bào)對(duì)象sendPacket,然后使用數(shù)據(jù)報(bào)套接字的send()方法將其發(fā)送給客戶(hù)端。19.3.2簡(jiǎn)單的UDP通信例子byte[]bufsend=newbyte[1024];try{varsocket=newDatagramSocket();varinput=newScanner(System.in);while(true){System.out.print("請(qǐng)輸入字符串:");varmessage=input.nextLine();bufsend=message.getBytes();//用于發(fā)送數(shù)據(jù)的數(shù)據(jù)報(bào)varpacket=newDatagramPacket( bufsend,message.length(),InetAddress.getLocalHost(),8888);程序19.5UDPClient.java//InetAddress.getByName("")socket.send(packet);if(message.equals("bye"))break;//用于接收數(shù)據(jù)的數(shù)據(jù)報(bào)byte[]bufrec=newbyte[1024];varreceivePacket= newDatagramPacket(bufrec,bufrec.length);socket.receive(receivePacket);varreceived=newString(bufrec,0,receivePacket.getLength());System.out.println("從服務(wù)器返回的字符串:"+received);}socket.close();首先啟動(dòng)服務(wù)器,它將等待客戶(hù)的請(qǐng)求。啟動(dòng)客戶(hù)端程序,提交一個(gè)字符串,服務(wù)器返回轉(zhuǎn)換后的字符串。服務(wù)器端程序的運(yùn)行結(jié)果如圖19-8,客戶(hù)端程序運(yùn)行結(jié)果如圖19-9所示。Java語(yǔ)言程序設(shè)計(jì)19.4基于HTTP的通信HTTP是指允許Web服務(wù)器和瀏覽器在互聯(lián)網(wǎng)上發(fā)送和接收數(shù)據(jù)的協(xié)議。它是一個(gè)基于請(qǐng)求和響應(yīng)的協(xié)議??蛻?hù)端向服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器對(duì)該請(qǐng)求做出響應(yīng)。HTTP使用可靠的TCP連接,默認(rèn)端口號(hào)是80。19.4.1理解HTTP在HTTP中,先由客戶(hù)端建立與服務(wù)器的連接并發(fā)送HTTP請(qǐng)求。Web服務(wù)器無(wú)權(quán)聯(lián)系客戶(hù)端??蛻?hù)端和服務(wù)器都可以提前終止連接。例如,在使用Web瀏覽器時(shí),可以單擊瀏覽器“停止”按鈕來(lái)終止下載文件,關(guān)閉與Web服務(wù)器的HTTP連接。由客戶(hù)向服務(wù)器發(fā)出的消息叫HTTP請(qǐng)求。HTTP請(qǐng)求通常包括請(qǐng)求行、請(qǐng)求頭、空行和請(qǐng)求的數(shù)據(jù)。圖19-10是一個(gè)典型的POST請(qǐng)求。HTTP的請(qǐng)求行由三部分組成:方法名、請(qǐng)求資源的URI和HTTP版本。這三部分由空格分隔。圖18.12的請(qǐng)求行中,方法為POST。HTTP1.1版支持7種請(qǐng)求,其中最常用的是GET和POST請(qǐng)求。1.HTTP請(qǐng)求結(jié)構(gòu)URI指定一個(gè)Web資源,它通常解釋為相對(duì)于服務(wù)器的根目錄。因此,它始終以一個(gè)正斜杠(/)開(kāi)頭。圖中的URI為/helloweb/selectProduct.do,使用的協(xié)議與版本為HTTP/1.1。1.HTTP請(qǐng)求結(jié)構(gòu)由服務(wù)器向客戶(hù)發(fā)送的HTTP消息稱(chēng)為HTTP響應(yīng),HTTP響應(yīng)也由三部分組成:狀態(tài)行、響應(yīng)頭和響應(yīng)的數(shù)據(jù)。圖19-11所示為一個(gè)典型的HTTP響應(yīng)消息。HTTP響應(yīng)的狀態(tài)行由三部分組成,各部分由空格分隔:HTTP版本、說(shuō)明請(qǐng)求結(jié)果的狀態(tài)碼以及描述狀態(tài)碼的短語(yǔ)。HTTP定義了許多狀態(tài)碼,常見(jiàn)的狀態(tài)碼是200,它表示請(qǐng)求被正常處理。狀態(tài)行之后的頭行稱(chēng)為響應(yīng)頭(responseheader)。響應(yīng)頭是服務(wù)器向客戶(hù)端發(fā)送的消息。圖19-11的響應(yīng)消息中包含三個(gè)響應(yīng)頭。Date響應(yīng)頭表示消息發(fā)送的日期,Content-Type響應(yīng)頭指定響應(yīng)的內(nèi)容類(lèi)型,Content-Length指示響應(yīng)內(nèi)容的長(zhǎng)度。響應(yīng)頭后面是一空行,空行的后面是響應(yīng)的數(shù)據(jù)2.HTTP響應(yīng)結(jié)構(gòu)2.HTTP響應(yīng)結(jié)構(gòu)URL稱(chēng)為統(tǒng)一資源定位器(UniformResourceLocator),它是Web中資源定位的方法。Web資源包括Web頁(yè)面、文本文件、圖形文件以及音頻和視頻片段等。19.4.2URL和URL類(lèi)URL的基本格式為:

<協(xié)議名://><主機(jī)名>[<:端口號(hào)>]</資源URI名>:80/en/index.htmlhttp://localhost:8080/webstore/selectProduct.do/包中提供了URL類(lèi)和URLConnection類(lèi)。使用這兩個(gè)類(lèi),可以讀寫(xiě)網(wǎng)絡(luò)資源。19.4.2URL和URL類(lèi)URL類(lèi)的常用構(gòu)造方法:

URL(Stringspec)URL(Stringprotocol,Stringhost,Stringfile)URL(Stringprotocol,Stringhost,intport,Stringfile)URL構(gòu)造方法拋出MalformedURLException異常,當(dāng)構(gòu)造方法參數(shù)無(wú)效就會(huì)拋出該異常。因此,當(dāng)創(chuàng)建URL對(duì)象時(shí)需要捕獲并處理這個(gè)異常。try{URLexampleURL=newURL("");}catch(MalformedURLExceptione){//異常處理代碼}19.4.2URL和URL類(lèi)URL類(lèi)提供的常用方法對(duì)URL對(duì)象的特征查詢(xún)和對(duì)URL對(duì)象的讀操作。StringgetProtocol()StringgetHost()intgetPort()InputStreamopenStream()URLConnectionopenConnection()19.4.2URL和URL類(lèi)try{varaURL=newURL("/javase/tutorial/"+"/index.html?name=networking#DOWNLOADING");System.out.println("protocol="+aURL.getProtocol());System.out.println("authority="+aURL.getAuthority());System.out.println("host="+aURL.getHost());System.out.println("port="+aURL.getPort());System.out.println("path="+aURL.getPath());System.out.println("query="+aURL.getQuery());System.out.println("filename="+aURL.getFile());System.out.println("ref="+aURL.getRef());}catch(MalformedURLExceptione){System.out.println("URL不合法");}程序19.6ParseURL.java在創(chuàng)建一個(gè)URL對(duì)象后,可以使用其openStream()方法建立一個(gè)連接并返回一個(gè)InputStream對(duì)象,然后就可以從這個(gè)對(duì)象上讀取數(shù)據(jù)。下面的例子說(shuō)明了該方法的使用,它通過(guò)URL對(duì)象讀取一個(gè)Web頁(yè)面信息。讀取Web資源try{varurl=newURL("");varin=newBufferedReader(newInputStreamReader(url.openStream()));varout=newFileWriter("index.html");StringinputLine;while((inputLine=in.readLine())!=null){out.write(inputLine);}in.close();out.close();}catch(MalformedURLExceptionme)

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論