Java程序設(shè)計課件11第十一章:網(wǎng)絡(luò)編程_第1頁
Java程序設(shè)計課件11第十一章:網(wǎng)絡(luò)編程_第2頁
Java程序設(shè)計課件11第十一章:網(wǎng)絡(luò)編程_第3頁
Java程序設(shè)計課件11第十一章:網(wǎng)絡(luò)編程_第4頁
Java程序設(shè)計課件11第十一章:網(wǎng)絡(luò)編程_第5頁
已閱讀5頁,還剩135頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

《JAVA程序設(shè)計》課程1、網(wǎng)絡(luò)的概念和網(wǎng)絡(luò)模型

主要內(nèi)容2、IP地址和端口號3、UDP和TCP通信協(xié)議Java程序設(shè)計4、基于UDP協(xié)議的SOCKET通信《JAVA程序設(shè)計》課程5、基于TCP協(xié)議的SOCKET通信

主要內(nèi)容6、URL、URLConnetion和HttpURLConnectionJava程序設(shè)計1.能了解OSI網(wǎng)絡(luò)模型和TCP/IP網(wǎng)絡(luò)模型的通信機制和過程《JAVA程序設(shè)計》課程

學(xué)習(xí)目標(biāo)2.能正確理解端口號的重要性,理解端口號和進程之間的關(guān)系3.能正確運用InetAddress類獲取主機的IP地址和域名4.能理解UDP協(xié)議和TCP在通訊時的差別5.能正確分析和編程實現(xiàn)基于UDP協(xié)議和TCP協(xié)議的SOCKET編程6.能運用URL、URLConnetion和HttpURLConnection實現(xiàn)簡單的編程11.1.1項目(11-1)描述《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念在聯(lián)網(wǎng)的情況下,獲取主機名為“”的IP地址列表。11.1.2項目知識準(zhǔn)備《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念(1)Client-Server體系構(gòu)架設(shè)想你去一家餐館,侍應(yīng)生送上菜單,在看過了充滿異國情調(diào)的菜式后,你點了一份匹薩。幾分鐘后,匹薩送來,上面涂滿了熱乳酪和其他你所想要的一切,你開始吃起來。你不知道也從不想知道侍應(yīng)生從哪兒端來這盤匹薩、它是怎么做出來的、其中的配料又是怎么弄到的。在上例中,所涉及的實體包括-------美味口的匹薩、提供服務(wù)的侍應(yīng)生、制作匹薩的廚房、當(dāng)然還有你,你是購買匹薩的顧客或客戶。匹薩的制作過程,對于你來說,完全是被封裝的。你的菜單在廚房進行處理,然后由侍應(yīng)生把匹薩端給你在上面所看到的就是一個客戶/服務(wù)器體系。其中,客戶向服務(wù)端下單或提出請求,服務(wù)器處理客戶的請求。在客戶/服務(wù)器體系中,客戶和服務(wù)器之間的通信是一個極為重要的組成部分,一般是能通過網(wǎng)絡(luò)完成的。客戶/服務(wù)器體系是應(yīng)用程序的一種開發(fā)構(gòu)架,這種構(gòu)架在設(shè)計上把數(shù)據(jù)的表示與其內(nèi)部處理和存儲分開。在這種體系中,客戶請求服務(wù),服務(wù)器提供服務(wù),客戶發(fā)出請求經(jīng)由網(wǎng)絡(luò)發(fā)送給服務(wù)器,服務(wù)器的處理過程對于客戶來說是不可見的,一個服務(wù)器可為多個客戶服務(wù)。11.1.2項目知識準(zhǔn)備服務(wù)端和客戶端數(shù)據(jù)傳輸?shù)姆绞饺鐖D11.1所示《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念ServerInternetClient1、提出要求4、接收數(shù)據(jù)3、傳遞數(shù)據(jù)2、接受要求圖11.1:Client-Server結(jié)構(gòu)圖(2)TCP/IP協(xié)議簇《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念TCP/IP為Internet上所使用的數(shù)據(jù)傳輸協(xié)議(protocol),TCP為TransmissionControlProtocol的縮寫,是傳輸控制協(xié)議;而IP為InternetProtocol的縮寫,是網(wǎng)絡(luò)互聯(lián)協(xié)議。所謂傳輸協(xié)議是指計算機和計算機溝通的語言。TCP/IP實際上是一組協(xié)議,包括多個具有不同功能且互為關(guān)聯(lián)的協(xié)議。TCP/IP是多個獨立定義的協(xié)議集合,因此也被稱為TCP/IP協(xié)議簇。TCP/IP協(xié)議模型從更實用的角度出發(fā),形成了高效的四層體系結(jié)構(gòu),即網(wǎng)絡(luò)接口層、IP層、傳輸層和應(yīng)用層。TCP/IP的分層結(jié)構(gòu)和OSI參考模型的對應(yīng)關(guān)系如圖11.2所示:《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念OSI模型TCP/IP模型應(yīng)用層

應(yīng)用層表示層會話層傳輸層傳輸層網(wǎng)絡(luò)層IP層數(shù)據(jù)鏈路層網(wǎng)絡(luò)接口層物理層(3)IP地址(InternetProtocol)《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念在互聯(lián)網(wǎng)上的每一臺計算機都有一個唯一表示自己的標(biāo)記,這個標(biāo)記就是IP地址,在windows操作系統(tǒng)中,用戶可以通過圖11.3所示的“Internet協(xié)議屬性”窗口來設(shè)置計算機的IP地址。IP地址使用32位長度二進制數(shù)據(jù)表示,一般在實際中看到的大部分IP地址都是以十進制的數(shù)據(jù)形式表示的,比如“00”等。IP地址的格式:IP地址=網(wǎng)絡(luò)地址+主機地址。其中網(wǎng)絡(luò)地址,也稱網(wǎng)絡(luò)號:用戶識別主機所在的網(wǎng)絡(luò);主機地址,也稱主機號:用戶識別該網(wǎng)絡(luò)中的主機。IP地址中的掩碼的功能主要是區(qū)分網(wǎng)絡(luò)號和主機號?!禞AVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念圖11.3Internet協(xié)議屬性窗口《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念在實際中可以使用表示本機地址,或者使用localhost也代表本機。由于IP地址不方便記憶,也可以使用域名來表示IP地址。域名和IP地址之間是有映射關(guān)系的,專門用于解析域名與IP地址之間映射關(guān)系的服務(wù)器,稱作DNS服務(wù)器。(4)端口《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念TCP與UDP都采用了應(yīng)用程序接口處的端口(port)與上層的應(yīng)用進程進行通信。端口是一個16位的地址,并用端口號進行標(biāo)識。端口號為兩類。一類是專門分配給一些最常用的應(yīng)用層程序,被稱為熟知端口,數(shù)值范圍為1-1024。另一類是一般的端口號,用來隨時分配給請求通信的客戶進程。通常一臺主機上總是有很多個進程需要網(wǎng)絡(luò)資源進行網(wǎng)絡(luò)通信。網(wǎng)絡(luò)通信的對象準(zhǔn)確地講不是主機,而應(yīng)該是主機中運行的進程。這時候光有主機名或IP地址來標(biāo)識數(shù)量較多的進程是不夠的。端口號就是為了在一臺主機上提供更多的網(wǎng)絡(luò)資源而采取的一種手段,也是TCP層提供的一種機制。只有通過主機名或IP地址和端口號的組合才能惟一確定網(wǎng)絡(luò)通信中的對象------進程。(5)InetAddress類《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念I(lǐng)netAddress的實例對象包含以數(shù)字形式保存的IP地址,同時還可能包含主機名。InetAddress類也提供了將主機名解析為IP地址(或反之)的方法。InetAddress的構(gòu)造函數(shù)不是公開的(public),所以需要通過它提供的靜態(tài)方法來獲取,有以下幾個常用的方法:staticInetAddress[]getAllByName(Stringhost)staticInetAddressgetByAddress(byte[]addr)staticInetAddressgetByAddress(Stringhost,byte[]addr)staticInetAddressgetByName(Stringhost)staticInetAddressgetLocalHost()《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念在這些靜態(tài)方法中,最為常用的應(yīng)該是getByName(Stringhost)方法,只需要傳入目標(biāo)主機的名字,InetAddress會嘗試做連接DNS服務(wù)器,并且獲取IP地址的操作。提醒:我們假設(shè)以下的代碼,都是默認導(dǎo)入了中的包,在程序的開頭加上import.*,否則需要指定類的全名.InetAddress。提醒:InetAddressaddress=InetAddress.getByName("");注意到這些方法可能會拋出的異常。如果安全管理器不允許訪問DNS服務(wù)器或禁止網(wǎng)絡(luò)連接,SecurityException會拋出,如果找不到對應(yīng)主機的IP地址,或者發(fā)生其他網(wǎng)絡(luò)I/O錯誤,這些方法會拋出UnknowHostException?!禞AVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念所以獲取IP的地址的代碼格式如下所示:try{InetAddressaddress=InetAddress.getByName("");System.out.println(address);}catch(UnknownHostExceptione){e.printStackTrace();}《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念案例11-1:獲取本機的IP地址和域名import.InetAddress;import.UnknownHostException;publicclassLocalInetAddressTest{ //測試InetAddress類 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddressaddr=InetAddress.getLocalHost();//獲取本機的對應(yīng)的InetAddress對象《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念Stringip=addr.getHostAddress();//獲取字符串形式的IP地址 StringhostName=addr.getHostName();//獲取域名 System.out.println("本機IP="+ip+"----->本機域名="+hostName); }}《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念案例11-2:通過IP地址獲取InetAddress對象并輸出相應(yīng)的IP地址和域名import.InetAddress;import.UnknownHostException;publicclassInetAddressTestByIP{ //測試InetAddress類 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddressaddr=InetAddress.getByName("7");//通過IP地址獲取InetAddress對象 Stringip=addr.getHostAddress();//獲取字符串形式的IP地址 StringhostName=addr.getHostName();//獲取域名 System.out.println("IP="+ip+"----->域名為="+hostName); }}案例11-3:獲取域名為“”的主機對應(yīng)的IP列表《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念提醒:若要通過域名獲取對應(yīng)該域名的所有的映射IP地址,可以通過方法getAllByName(“主機域名”)實現(xiàn)。代碼如下所示:import.InetAddress;import.UnknownHostException;publicclassBaiDuInetAddressTest{ //測試的IP列表 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddress[]addr=InetAddress.getAllByName(""); for(InetAddressx:addr){ Stringip=x.getHostAddress();//字符串形式的ip地址 StringhostName=x.getHostName(); System.out.println("IP="+ip+"----->"+hostName); } }案例11-3:獲取域名為“”的主機對應(yīng)的IP列表提醒:若要通過域名獲取對應(yīng)該域名的所有的映射IP地址,可以通過方法getAllByName(“主機域名”)實現(xiàn)。代碼如下所示:import.InetAddress;import.UnknownHostException;publicclassBaiDuInetAddressTest{ //測試的IP列表 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddress[]addr=InetAddress.getAllByName(""); for(InetAddressx:addr){ Stringip=x.getHostAddress();//字符串形式的ip地址 StringhostName=x.getHostName(); System.out.println("IP="+ip+"----->"+hostName); } }《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念運行結(jié)果如圖11.4所示圖11.4域名為“”的主機IP列表11.1.3項目實施《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念(1)分析通過分析題目可以得出以下信息:①已知條件是主機域名為“”;②目標(biāo)是輸出該域名對應(yīng)的IP列表,要想獲取IP列表則需要使用方法getAllByName();③由于是操作InetAddress類,需要進行域名解析操作,所以異常聲明或異常捕獲是必要的。(2)編碼:《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念通過以上分析我們可以編寫以下代碼實現(xiàn)功能:import.InetAddress;import.UnknownHostException;publicclassBaiDuInetAddressTest{ //測試的IP列表 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddress[]addr=InetAddress.getAllByName(""); for(InetAddressx:addr){ Stringip=x.getHostAddress();//字符串形式的IP地址 StringhostName=x.getHostName(); System.out.println("IP="+ip+"----->"+hostName); } }}(3)調(diào)試運行,顯示結(jié)果《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念該程序的運行結(jié)果如圖11.5所示:圖11.5“”域名對應(yīng)的IP列表11.1.4能力拓展《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念(1)選擇題①TCP協(xié)議棧的四層結(jié)構(gòu)中不包括(D)A.應(yīng)用層B.傳輸層C.網(wǎng)絡(luò)層D.會話層②獲取本機地址可以使用下面哪個方法(B)A.getHostName()B.getLocalHost()C.getByName()D.getHostAddress()

(2)填空題①目前最廣泛使用的網(wǎng)絡(luò)協(xié)議是Internet上使用的(TCP/IP)協(xié)議②套接字是一個特定機器上被編號的(端口),系統(tǒng)可用的端口號是(1-1024),用戶可用的端口號是(1025-65535)③通過域名獲取IP列表使用的方法是(getByAllName())(3)編程《JAVA程序設(shè)計》課程

11.1網(wǎng)絡(luò)編程的基本概念①編程實現(xiàn)本課中的案例11-1至案例11-3的功能,并運行測試。②編程實現(xiàn)獲取“”的IP列表,并運行測試。③編程實現(xiàn)本節(jié)課中的項目11-1中的功能,并運行測試。11.2.1項目(11-2)描述《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計使用UDP協(xié)議實現(xiàn)某網(wǎng)段的群聊功能。要求從鍵盤打字,直到某人輸入“over”表示他退出聊天室;其他人可以繼續(xù)聊。11.2.2項目知識準(zhǔn)備《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計(1)UDP與TCP協(xié)議UDP在傳送數(shù)據(jù)之前,不需要建立連接,同時,遠程主機收到UDP數(shù)據(jù)包后,不需要返回任何響應(yīng)。TCP提供面向連接的服務(wù)。TCP不支持廣播或多播服務(wù)。由于TCP要提供運輸服務(wù),因此TCP不可避免地增加了許多開銷,如應(yīng)答、流量控制、定時器以及連接管理等。這樣既增加了協(xié)議頭,也占用了更多的CPU時間。①IP協(xié)議IP協(xié)議用于管理客戶端和服務(wù)端之間的報文傳送。IP協(xié)議是所有Internet協(xié)議的基石,IP協(xié)議是一個面向包的協(xié)議,是無連接的。IP協(xié)議已經(jīng)成為世界上最重要國際協(xié)議?!禞AVA程序設(shè)計》課程

11.2UDP程序設(shè)計(1)UDP與TCP協(xié)議UDP在傳送數(shù)據(jù)之前,不需要建立連接,同時,遠程主機收到UDP數(shù)據(jù)包后,不需要返回任何響應(yīng)。TCP提供面向連接的服務(wù)。TCP不支持廣播或多播服務(wù)。由于TCP要提供運輸服務(wù),因此TCP不可避免地增加了許多開銷,如應(yīng)答、流量控制、定時器以及連接管理等。這樣既增加了協(xié)議頭,也占用了更多的CPU時間。①IP協(xié)議IP協(xié)議用于管理客戶端和服務(wù)端之間的報文傳送。IP協(xié)議是所有Internet協(xié)議的基石,IP協(xié)議是一個面向包的協(xié)議,是無連接的。IP協(xié)議已經(jīng)成為世界上最重要國際協(xié)議。③TCP協(xié)議TCP(TransmissionControlProtocol)即傳輸控制協(xié)議,是一個面向連接的協(xié)議,它提供雙向的、可靠的、有流量控制的字節(jié)流的服務(wù)。字節(jié)流服務(wù)的意思是:在一個TCP連接中,源節(jié)點發(fā)送一連串的字節(jié)給目標(biāo)節(jié)點《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計TCP協(xié)議有幾項特點:<1>確認回應(yīng)當(dāng)甲計算機傳送數(shù)據(jù)到乙計算機時,會等待乙計算機返回確認后才會再傳送下一筆數(shù)據(jù)。當(dāng)一段時間內(nèi)沒有收到乙計算機的確認回應(yīng),甲計算機會試著再傳送一次,如果傳送了很多次都沒有回應(yīng),就表示鏈接可能斷了。此特征可以很容易地知道網(wǎng)絡(luò)鏈接的狀況。<2>數(shù)據(jù)包序號面向連接協(xié)議在傳送數(shù)據(jù)時,會把數(shù)據(jù)切成固定大小的數(shù)據(jù)包(packet),然后在每個數(shù)據(jù)包上加上序號。這樣的好處是接收端可以檢查收到的是哪些數(shù)據(jù)包、哪些數(shù)據(jù)包重復(fù)等。<3>流量控制有了<1>和<2>兩項特征,就可以控制傳輸?shù)牧髁俊?/p>

《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計案例11-4:設(shè)計一個發(fā)送、接收程序,發(fā)送端向接收端發(fā)送數(shù)據(jù)。接收端接收數(shù)據(jù),并把數(shù)據(jù)打印到控制臺中。重點:基于UDP協(xié)議的發(fā)送端發(fā)送數(shù)據(jù)的步驟有四步:(1)建立發(fā)送端對象。(2)建立數(shù)據(jù)包(發(fā)送格式)。DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)(3)調(diào)用Socket的發(fā)送方法。(4)關(guān)閉Socket?!禞AVA程序設(shè)計》課程

11.2UDP程序設(shè)計importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassSendSocket{ /**UDP *1.建立發(fā)送端對象。 *2.建立數(shù)據(jù)包(發(fā)送格式)。

發(fā)送端代碼如下:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計*DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport) *3.調(diào)用Socket的發(fā)送方法。 *4.關(guān)閉Socket。 *@throwsIOException */ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建Socket對象 DatagramSocketsendSocket=newDatagramSocket(20000);//此時的端口號為客戶端發(fā)送數(shù)據(jù)的端口號,跟服務(wù)器端的接受數(shù)據(jù)的端口號可以不一致?!禞AVA程序設(shè)計》課程

11.2UDP程序設(shè)計//2.創(chuàng)建數(shù)據(jù)包對象 byte[]data="你好,我是客戶端小明".getBytes(); InetAddressaddress=InetAddress.getByName("cqvie-xxw"); DatagramPacketpacket=newDatagramPacket(data,0,data.length,address,10000); //3.發(fā)送數(shù)據(jù) sendSocket.send(packet); //4.關(guān)閉socket sendSocket.close(); }}接收端主要操作步驟:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計重點:基于UDP協(xié)議的接收端接收數(shù)據(jù)的步驟有四步:(1)建立接收端對象。(2)建立數(shù)據(jù)包(接收格式)。DatagramPacket(byte[]buf,intlength)(3)調(diào)用Socket的接收方法。(4)關(guān)閉接收端Socket。接收端代碼如下《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassReceiveSocket{ /** *1.建立接收端對象。 *2.建立數(shù)據(jù)包(發(fā)送格式)。 *DatagramPacket(byte[]buf,intlength) *3.調(diào)用Socket的接收方法。 *4.關(guān)閉接收端Socket?!禞AVA程序設(shè)計》課程

11.2UDP程序設(shè)計*@throwsIOException */ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建Socket對象 DatagramSocketrecevieSocket=newDatagramSocket(10000); //2.創(chuàng)建數(shù)據(jù)包對象 byte[]data=newbyte[1024]; DatagramPacketpacket=newDatagramPacket(data,data.length); //3.發(fā)送數(shù)據(jù) recevieSocket.receive(packet);//阻塞式方法 //從包裹中取數(shù)據(jù)及其他內(nèi)容《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計InetAddressaddress=packet.getAddress();//獲取發(fā)送方的IP對象 byte[]sourceData=packet.getData();//獲取發(fā)送方的數(shù)據(jù) intlen=packet.getLength();//獲取發(fā)送發(fā)發(fā)送的數(shù)據(jù)的有效長度:單位為字節(jié)數(shù) intport=packet.getPort();//獲取發(fā)送方的端口號 Stringtext=newString(sourceData,0,len);//把字節(jié)數(shù)組轉(zhuǎn)換為字符串 System.out.println("接收到IP="+address.getHostAddress()+",端口號="+port+"的數(shù)據(jù)----->"+text); //4.關(guān)閉socket recevieSocket.close(); }}先運行接收端程序,讓接收端處于等待接收狀態(tài),然后再運行發(fā)送端程序,則在接收端就收到了發(fā)送端的數(shù)據(jù),程序運行結(jié)果如圖11.6所示:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計圖11.6案例11-4運行結(jié)果圖《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計案例11-5:實現(xiàn)簡單的聊天功能,即發(fā)送端從鍵盤打字,按回車鍵發(fā)送數(shù)據(jù)給接收端,接收端接收數(shù)據(jù)后,把數(shù)據(jù)輸出到控制臺中;這樣重復(fù)進行,直到發(fā)送端發(fā)送“over”結(jié)束聊天功能。分析:本功能比案例11-4多了不停的通過鍵盤打字功能,這里要使用到IO流操作。具體發(fā)送端和接收端代碼如下所示。發(fā)送端代碼:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassChatSendSocket{

《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計/**UDP協(xié)議 *1.建立發(fā)送端對象。 *2.建立數(shù)據(jù)包(發(fā)送格式)。 *DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport) *3.調(diào)用Socket的發(fā)送方法。 *4.關(guān)閉Socket。 *@throwsIOException */publicstaticvoidmain(String[]args)throwsIOException{//1.創(chuàng)建Socket對象 DatagramSocketsendSocket=newDatagramSocket(20000);《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計//從鍵盤輸入數(shù)據(jù),按行來發(fā)送數(shù)據(jù) InputStreamis=System.in; //把字節(jié)流轉(zhuǎn)換為字符流 InputStreamReaderisr=newInputStreamReader(is); //裝飾 BufferedReaderbr=newBufferedReader(isr); StringlineData=null; while((lineData=br.readLine())!=null){ //2.創(chuàng)建數(shù)據(jù)包對象 byte[]data=lineData.getBytes();《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計InetAddressaddress=InetAddress.getByName("7"); DatagramPacketpacket=newDatagramPacket(data,0,data.length,address,10000); //3.發(fā)送數(shù)據(jù) sendSocket.send(packet); if(lineData.equals("over")) break; } //4.關(guān)閉socket sendSocket.close(); }接收端程序代碼如下:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassChatReceiveSocket{ publicstaticvoidmain(String[]args)throwsIOException{//1.創(chuàng)建Socket對象DatagramSocketrecevieSocket=newDatagramSocket(10000);《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計//2.創(chuàng)建數(shù)據(jù)包對象 byte[]data=newbyte[1024]; DatagramPacketpacket=newDatagramPacket(data,data.length); //3.接收數(shù)據(jù) while(true){ recevieSocket.receive(packet);//阻塞式方法 //從包裹中取數(shù)據(jù)及其他內(nèi)容 InetAddressaddress=packet.getAddress();//獲取發(fā)送方的IP對象 byte[]sourceData=packet.getData();//獲取發(fā)送方的數(shù)據(jù)《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計intlen=packet.getLength();//獲取發(fā)送發(fā)發(fā)送的數(shù)據(jù)的有效長度:單位為字節(jié)數(shù) Stringtext=newString(sourceData,0,len);//把字節(jié)數(shù)組轉(zhuǎn)換為字符串 if(text.equals("over")){ System.out.println("IP="+address.getHostAddress()+"的人和你的聊天結(jié)束"); break; }else System.out.println("IP="+address.getHostAddress()+"說:----->" +text); } //4.關(guān)閉socket《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計recevieSocket.close(); }}先運行接收端程序,再運行發(fā)送端程序,其運行結(jié)果如圖11.7所示:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計圖11.7案例11-5的運行結(jié)果圖11.2.3項目實施《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計(1)分析通過分析題目可以得出以下信息:①假設(shè)某網(wǎng)段的廣播地址為“55”;②由于是基于UDP協(xié)議的通信,所以客戶端和接收端都要遵守四個步驟③由于是UDP協(xié)議的通信,需要DatagramSocket類和DatagramPacket類,由于有可能出現(xiàn)異常,所以異常聲明或異常捕獲是必要的;④由于需要從鍵盤輸入文本數(shù)據(jù),所以需要IO流。《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計(2)發(fā)送端代碼:通過以上分析我們可以編寫以下代碼實現(xiàn)功能發(fā)送端功能:提醒:如果要實現(xiàn)群聊功能,則要把數(shù)據(jù)發(fā)送給網(wǎng)段的廣播地址,比如某一網(wǎng)段的網(wǎng)址為192.168.0.X,則其廣播地址為55。importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;import.DatagramPacket;import.DatagramSocket;import.InetAddress;《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計publicclassChatSendSocket1{ /**UDP協(xié)議 *1.建立發(fā)送端對象。 *2.建立數(shù)據(jù)包(發(fā)送格式)。 *DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport) *3.調(diào)用Socket的發(fā)送方法。 *4.關(guān)閉Socket。 *@throwsIOException */ publicstaticvoidmain(String[]args)throwsIOException{《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計//1.創(chuàng)建Socket對象 DatagramSocketsendSocket=newDatagramSocket(20000); //從鍵盤輸入數(shù)據(jù),按行來發(fā)送數(shù)據(jù) InputStreamis=System.in; //把字節(jié)流轉(zhuǎn)換為字符流 InputStreamReaderisr=newInputStreamReader(is); //裝飾 BufferedReaderbr=newBufferedReader(isr); StringlineData=null; while((lineData=br.readLine())!=null){《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計//2.創(chuàng)建數(shù)據(jù)包對象 byte[]data=lineData.getBytes(); InetAddressaddress=InetAddress.getByName("55");//55是網(wǎng)段的廣播地址DatagramPacketpacket=newDatagramPacket(data,0,data.length,address,10000); //3.發(fā)送數(shù)據(jù) sendSocket.send(packet); if(lineData.equals("over")) break;《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計} //4.關(guān)閉socket sendSocket.close(); }}《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計(3)接收端代碼:接收方的代碼如下所示:importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassChatReceiveSocket1{ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建Socket對象《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計DatagramSocketrecevieSocket=newDatagramSocket(10000); //2.創(chuàng)建數(shù)據(jù)包對象 byte[]data=newbyte[1024]; DatagramPacketpacket=newDatagramPacket(data,data.length); //3.接收數(shù)據(jù) while(true){ recevieSocket.receive(packet);//阻塞式方法 //從包裹中取數(shù)據(jù)及其他內(nèi)容 InetAddressaddress=packet.getAddress();//獲取發(fā)送方的IP對象 byte[]sourceData=packet.getData();//獲取發(fā)送方的數(shù)據(jù) intlen=packet.getLength();//獲取發(fā)送發(fā)發(fā)送的數(shù)據(jù)的有效長度:單位為字節(jié)數(shù)《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計Stringtext=newString(sourceData,0,len);//把字節(jié)數(shù)組轉(zhuǎn)換為字符串 if(text.equals("over")){ System.out.println("IP="+address.getHostAddress()+"的人退出了聊天室");//break;//即便輸入over結(jié)束聊天,在接收端也不退出循環(huán) } else System.out.println("IP="+address.getHostAddress()+"說:----->" +text); }// 4.取消關(guān)閉socket// recevieSocket.close(); }}4)調(diào)試運行,顯示結(jié)果該程序的運行結(jié)果如圖11.8所示:《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計圖11.8域名為“”的主機IP列表11.2.4能力拓展《JAVA程序設(shè)計》課程

11.2UDP程序設(shè)計(1)選擇題①一個Socket由(A)唯一確定A.一個IP地址和一個端口號B.一個IP地址和一個主機名C.一個主機號和一個端口號D.一個IP地址②基于UDP協(xié)議的編程中用來表示通訊端點(即套接字)的類是(B)A.SocketB.DatagramSocketC.ServerSocketD.DatagramPacket(2)填空題①TCP/IP協(xié)議的兩種通信協(xié)議是(TCP)協(xié)議和(UDP)協(xié)議②常用的編程模式有客戶端/(服務(wù)器)模式和B/S模式③在JAVA中基于UDP協(xié)議編程時,需要使用數(shù)據(jù)包,在JAVA中描述數(shù)據(jù)包的類是(DatagramPacket),這個類的構(gòu)造方法共有6種形式的重載,其中(4)個是發(fā)送形式的,(2)個是表示接受形式的?!禞AVA程序設(shè)計》課程

11.2UDP程序設(shè)計3)編程①編程實現(xiàn)本課中的案例11-4至案例11-5的編碼。②實現(xiàn)本節(jié)課程中項目11-2的功能,并運行測試。11.3.1項目(11-3)描述《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計使用TCP協(xié)議實現(xiàn)一個圖片上傳服務(wù)器功能,即各個客戶端使用多線程技術(shù)可以向一個IP為7的服務(wù)器上上傳圖片,服務(wù)器接收上傳的圖片并將圖片保存到服務(wù)器的本地文件。11.3.2項目知識準(zhǔn)備《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計TCP(TransmissionControlProtocol)即傳輸控制協(xié)議,是一個面向連接的協(xié)議,它提供雙向的、可靠的、有流量控制的字節(jié)流的服務(wù)。在JAVA中使用Socket完成TCP程序的設(shè)計,使用此類可以方便地建立可靠的、雙向的、持續(xù)的、點對點的通訊連接。在Socket的程序開發(fā)中,服務(wù)器端使用ServerSocket等待客戶端的連接,對于JAVA的網(wǎng)絡(luò)程序來講,每一個客戶端都要使用一個Socket對象表示。如圖11.9所示:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計圖11.9基于TCP協(xié)議的客戶端和服務(wù)器端的通訊模型Client的SocketAccept服務(wù)器端的ServerSocketClient的Socket(2)基于TCP的客戶端套接字Socket《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計Socket:套接字,相當(dāng)于插到插線板上的插頭,基于TCP實現(xiàn)網(wǎng)絡(luò)通信。一個socket是兩臺機器通信的端點。①套接字能執(zhí)行的基本操作主要有以下7種:<1>連接到遠程機器;<2>綁定到端口;<3>接收從遠程機器來的連接請求;<4>監(jiān)聽到達的數(shù)據(jù);<5>發(fā)送數(shù)據(jù);<6>接收數(shù)據(jù);《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計<7>關(guān)閉連接;②Socket類主要用到兩個構(gòu)造方法:publicSocket(InetAddress

address,int

port)throwsIOException:創(chuàng)建一個流套接字并將其連接到指定IP地址的指定端口號。參數(shù):address-IP地址。port-端口號?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計拋出:UnknownHostException-如果無法確定主機的IP地址。IOException-如果創(chuàng)建套接字時發(fā)生I/O錯誤。Socket對象常用到的方法如下:③常見方法publicInetAddressgetInetAddress():返回套接字連接的地址。返回:此套接字連接到的遠程IP地址;如果套接字是未連接的,則返回null。publicintgetPort():返回此套接字連接到的遠程端口。返回:此套接字連接到的遠程端口號;如果尚未連接套接字,則返回0?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計publicintgetLocalPort():返回此套接字綁定到的本地端口。返回:此套接字綁定到的本地端口號;如果尚未綁定套接字,則返回-1。publicInetAddressgetLocalAddress():獲取套接字綁定的本地地址。返回:將套接字綁定到的本地地址;如果尚未綁定套接字,則返回InetAddress.anyLocalAddress()。publicInetAddressgetInetAddress()返回套接字連接的地址。返回:此套接字連接到的遠程IP地址;如果套接字是未連接的,則返回null?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計publicInputStreamgetInputStream()throwsIOException返回此套接字的輸入流。publicOutputStreamgetOutputStream()throwsIOException返回此套接字的輸出流。publicvoidclose()throwsIOException關(guān)閉此套接字。publicStringtoString()將此套接字轉(zhuǎn)換為String。(3)基于TCP的服務(wù)器端套接字ServerSocket類《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計在客戶端-服務(wù)器的網(wǎng)絡(luò)模型中,利用Socket我們可以輕松開發(fā)一個客戶端程序,同樣我們利用ServerSocket可以開發(fā)服務(wù)器程序。ServerSocket:服務(wù)器套接字,相當(dāng)于插線板?;赥CP實現(xiàn)網(wǎng)絡(luò)通信。一個服務(wù)器socket等待網(wǎng)絡(luò)上來的請求。它執(zhí)行某些基于請求的操作,然后可能返回一個結(jié)果給請求者。①ServerSocket工作流程<1>在指定的監(jiān)聽端口創(chuàng)建一個ServerSocket對象。<2>ServerSocket對象調(diào)用accept()方法在指定的端口監(jiān)聽到來的連接。accept()阻塞當(dāng)前Java線程,直到收到客戶端連接請求,accept()方法返回連接客戶端與服務(wù)器的Socket對象。<3>調(diào)用getInputStream()方法和getOutputStream()方法獲得Socket對象的輸入和輸出流?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計<4>服務(wù)器與客戶端根據(jù)一定的協(xié)議交互數(shù)據(jù),直到一端請求關(guān)閉連接。<5>服務(wù)器與客戶端關(guān)閉連接<6>服務(wù)器回到第2步,繼續(xù)監(jiān)聽下一次的連接。而客戶端則運行結(jié)束。②ServerSocket類的構(gòu)建器有:ServerSocket():創(chuàng)建非綁定服務(wù)器套接字。ServerSocket(int

port):創(chuàng)建綁定到特定端口的服務(wù)器套接字。ServerSocket(int

port,int

backlog):《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計創(chuàng)建服務(wù)器套接字并將其綁定到指定的本地端口號。ServerSocket(int

port,int

backlog,InetAddress

bindAddr):使用指定的端口、偵聽backlog和要綁定到的本地IP地址創(chuàng)建服務(wù)器。③ServerSocket類主要方法accept():偵聽并接受到此套接字的連接。bind(SocketAddress

endpoint):將ServerSocket綁定到特定地址(IP地址和端口號)。bind(SocketAddress

endpoint,int

backlog):將ServerSocket綁定到特定地址(IP地址和端口號)?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計close():關(guān)閉此套接字。getChannel():返回與此套接字關(guān)聯(lián)的唯一ServerSocketChannel對象(如果有)。getInetAddress():返回此服務(wù)器套接字的本地地址。getLocalPort():

返回此套接字在其上偵聽的端口。getLocalSocketAddress():返回此套接字綁定的端點的地址,如果尚未綁定則返回null。getReceiveBufferSize():《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計獲取此ServerSocket的SO_RCVBUF選項的值,該值是將用于從此ServerSocket接受的套接字的建議緩沖區(qū)大小。getReuseAddress():測試是否啟用SO_REUSEADDR。getSoTimeout():獲取SO_TIMEOUT的設(shè)置。implAccept(Socket

s):ServerSocket的子類使用此方法重寫accept()以返回它們自己的套接字子類。isBound():返回ServerSocket的綁定狀態(tài)。isClosed():返回ServerSocket的關(guān)閉狀態(tài)《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計rformancePrefsetPeerences(intconnectionTime,intlatency,intbandwidth):設(shè)置此ServerSocket的性能首選項。setReceiveBufferSize(int

size):為從此ServerSocket接受的套接字的SO_RCVBUF選項設(shè)置默認建議值。setReuseAddress(booleanon):啟用/禁用SO_REUSEADDR套接字選項。setSoTimeout(int

timeout)通過指定超時值,以毫秒為單位。④服務(wù)器與客戶機之間的通信過程如下圖11.10所示《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計圖11.10:服務(wù)器與客戶機的通信《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計1.客戶端發(fā)出連接Client1socketClient2socket為Client1創(chuàng)建的Socket為Client2創(chuàng)建的SocketServerClient2.服務(wù)器接受請求并創(chuàng)建新的Socket3.兩個Socket之間建立專線連接案例11-6:設(shè)計一個發(fā)送、接收程序,發(fā)送端向接收端發(fā)送數(shù)據(jù)。接收端接收數(shù)據(jù),并把數(shù)據(jù)打印到控制臺中。發(fā)送端主要操作步驟:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計重點:基于TCP協(xié)議的客戶端發(fā)送數(shù)據(jù)的步驟有五步:(1)建立客戶端對象,明確服務(wù)器的IP和端口號;(2)若建立連接成功,則可以通過getOutputStream()獲取輸出流,也可以通過getInputStream()獲取輸入流;(3)使用輸出流向服務(wù)器端輸出數(shù)據(jù);(4)使用輸入流獲取服務(wù)器端返回的數(shù)據(jù);(5)關(guān)閉Socket。在本案例中是向服務(wù)器發(fā)送數(shù)據(jù),并不接收服務(wù)器的數(shù)據(jù),所以主要使用到了(1)、(2)、(3)、(5)四個步驟??蛻舳舜a如下:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計importjava.io.IOException;importjava.io.OutputStream;import.Socket;import.UnknownHostException;publicclassClientDemo{ /** *客戶端發(fā)數(shù)據(jù)到服務(wù)端 *Tcp傳輸,客戶端建立的過程。《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計*1.創(chuàng)建tcp客戶端socket服務(wù)。使用的是Socket對象。 * 建議該對象創(chuàng)建時就明確目的地。要連接的主機。 *2.如果連接建立成功,說明數(shù)據(jù)傳輸通道已建立。 * 可以通過getOutputStream(),和getInputStream()來獲取兩個字節(jié)流。 *3.使用輸出流,將數(shù)據(jù)寫出。 *4.關(guān)閉資源。 */ publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{ //創(chuàng)建客戶端socket服務(wù)?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計Socketsocket=newSocket("7",10002); //獲取socket流中的輸出流。 OutputStreamout=socket.getOutputStream(); //使用輸出流將指定的數(shù)據(jù)寫出去。 out.write("你好,這是來自客戶端的數(shù)據(jù)".getBytes()); //關(guān)閉資源。 socket.close(); }}服務(wù)器端編程的主要操作步驟:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計重點:基于TCP協(xié)議的服務(wù)器端接收數(shù)據(jù)的步驟有六步:(1)建立接服務(wù)器端的ServerSocket對象,服務(wù)器端Socket必須對外提供一個端口,否則客戶端無法連接;(2)獲取客戶端的Socket對象;(3)通過getOutputStream()來獲取服務(wù)器端的輸出流,和getInputStream()來獲取服務(wù)器端的輸入流;(4)通過輸入流獲取客戶端的數(shù)據(jù);(5)通過輸出流向客戶端發(fā)送數(shù)據(jù);(6)關(guān)閉客戶端的Socket對象和服務(wù)器端的ServerSocket對象。在本案例中只是接收客戶端的數(shù)據(jù),并不向客戶端發(fā)送數(shù)據(jù),所以需要上述的(1)、(2)、(3)、(4)、(6)接收端代碼如下《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計importjava.io.IOException;importjava.io.InputStream;import.ServerSocket;import.Socket;publicclassServerDemo{ //服務(wù)端接收客戶端發(fā)送過來的數(shù)據(jù),并打印在控制臺上。 /* *建立tcp服務(wù)端的思路:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計*1,創(chuàng)建服務(wù)端的端點ServerSocket對象。 *2,服務(wù)器端ServerSocket對象必須對外提供一個端口,否則客戶端無法連接。 *3,獲取連接過來的客戶端對象。 *4,通過客戶端對象獲取socket流讀取客戶端發(fā)來的數(shù)據(jù) * 并打印在控制臺上。 *5,關(guān)閉資源。關(guān)客戶端,關(guān)服務(wù)器端。 */ publicstaticvoidmain(String[]args)throwsIOException{//1.創(chuàng)建服務(wù)端對象。 ServerSocketss=newServerSocket(10002);《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計//2.獲取連接過來的客戶端對象。 Sockets=ss.accept();//阻塞式. Stringip=s.getInetAddress().getHostAddress(); //3.通過socket對象獲取輸入流,要讀取客戶端發(fā)來的數(shù)據(jù) InputStreamin=s.getInputStream(); //4.讀取數(shù)據(jù) byte[]buf=newbyte[1024]; intlen=in.read(buf); Stringtext=newString(buf,0,len); System.out.println(ip+":"+text); //5.關(guān)閉Socket 《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計s.close(); ss.close(); }}先運行服務(wù)器端程序,服務(wù)器端的程序處于等待接收狀態(tài),然后再運行客戶端程序,則服務(wù)器端的程序就收到了客戶端的數(shù)據(jù),程序運行結(jié)果如圖11.11所示:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計圖11.11案例11-6運行結(jié)果圖案例11-7:使用TCP協(xié)議實現(xiàn)客戶端和服務(wù)器端相互發(fā)數(shù)據(jù)功能。分析:本案例功能比案例11-6多了部分功能,在客戶端多了接收服務(wù)器端返回數(shù)據(jù)的功能,在服務(wù)器端多了向客戶端發(fā)送數(shù)據(jù)的功能??蛻舳舜a如下:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;import.Socket;import.UnknownHostException;publicclassClientDemo2{ publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計//1.創(chuàng)建客戶端的Socket對象 Socketsocket=newSocket("7",10002); //2.獲取客戶端的輸出流out OutputStreamout=socket.getOutputStream(); //3.通過輸出流向服務(wù)器端發(fā)送數(shù)據(jù) out.write("你好,這是客戶端向服務(wù)器端發(fā)送的數(shù)據(jù)".getBytes()); //4.接收服務(wù)端返回的數(shù)據(jù),使用socket讀取流。 InputStreamin=socket.getInputStream(); byte[]buf=newbyte[1024];

《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計intlen=in.read(buf); Stringtext=newString(buf,0,len); System.out.println(text); //5.關(guān)閉資源。 socket.close(); }}服務(wù)器端程序代碼如下:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;import.ServerSocket;import.Socket;publicclassServerDemo2{ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建服務(wù)端對象。 ServerSocketss=newServerSocket(10002);《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計//2.獲取連接過來的客戶端對象。 Sockets=ss.accept(); Stringip=s.getInetAddress().getHostAddress(); //3.通過socket對象獲取輸入流, InputStreamin=s.getInputStream(); //4.讀取客戶端發(fā)來的數(shù)據(jù) byte[]buf=newbyte[1024];intlen=in.read(buf); Stringtext=newString(buf,0,len); System.out.println(ip+":"+text);《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計//5.使用客戶端socket對象的輸出流給客戶端返回數(shù)據(jù) OutputStreamout=s.getOutputStream(); out.write("我是服務(wù)器端,我收到你發(fā)送的數(shù)據(jù)".getBytes()); //6.關(guān)閉socket s.close();//s關(guān)閉時同時關(guān)閉了in和out兩個流 ss.close(); }}《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計先運行服務(wù)器端程序,再運行客戶端程序,其運行結(jié)果如圖11.12所示:提醒:本例中客戶端sokect.close()關(guān)閉了客戶端的輸入流和輸出流,同樣在服務(wù)器端s.close()也關(guān)閉了服務(wù)器端的輸入流和輸出流?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計圖11.12案例11-7的運行結(jié)果圖案例11-8:使用TCP協(xié)議實現(xiàn)客戶端向服務(wù)器端上傳圖片功能。分析:本案例功能比較簡單即在案例11-7的基礎(chǔ)上改進即可,因為發(fā)送的不是一句話,而是一個圖片文件,這里要使用IO流來實現(xiàn)輸入和輸出文件操作??蛻舳舜a如下:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計import.Socket;import.UnknownHostException;publicclassUploadPicClient{ publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{ //1.創(chuàng)建客戶端socket。 Sockets=newSocket("7",10003); //2.讀取客戶端要上傳的圖片文件。使用文件輸入流讀取圖片中的數(shù)據(jù) FileInputStreamfis=newFileInputStream("d:\\a.png"); //3.獲取socket輸出流。}《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計服務(wù)器端程序代碼如下:提醒:本例中客戶端程序中的s.shutdownOutput();語句比較重要,它的意思是告訴服務(wù)端:客戶端的數(shù)據(jù)發(fā)送完畢。讓服務(wù)端停止讀取。importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計import.ServerSocket;import.Socket;publicclassUploadPicServer{ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建tcp的socket服務(wù)端。 ServerSocketss=newServerSocket(10003); //2.通過循環(huán),依次接收客戶端發(fā)送的數(shù)據(jù) while(true){ Sockets=ss.accept();《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計Stringip=s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); try{ //3.獲取輸入流 InputStreamin=s.getInputStream(); //4.將讀取到數(shù)據(jù)存儲到一個文件中。 Filedir=newFile("d:\\pic");//圖片保存到服務(wù)器的d:盤的pic目錄中 if(!dir.exists()){ dir.mkdir();《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計} Filefile=newFile(dir,ip+".png");//圖片的擴展名為png格式 FileOutputStreamfos=newFileOutputStream(file); byte[]buf=newbyte[1024]; intlen=0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } //5.獲取socket輸出流,將圖片上傳成功告之客戶端?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計OutputStreamout=s.getOutputStream(); out.write("圖片上傳成功".getBytes()); //6.關(guān)閉socket fos.close();//單獨關(guān)閉文件輸出流 s.close(); System.out.println("客戶端IP="+ip+"的客戶上傳圖片成功!"); }catch(IOExceptione){ System.out.println(e.getMessage()); } }《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計//ss.close();//服務(wù)器端一直等待接收客戶端的數(shù)據(jù),就不能關(guān)閉了 }}提醒:在本案例中使用了dir.exists(),是判斷服務(wù)器端的d盤下是否存在pic目錄,如果不存在,則創(chuàng)建該目錄。先運行服務(wù)器端程序,再運行客戶端程序,其運行結(jié)果如圖11.13所示:《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計圖11.13案例11-8的運行結(jié)果圖11.3.3項目實施《JAVA程序設(shè)計》課程11.3TCP程序設(shè)計1)分析通過分析題目可以得出以下信息:①本題目是基于TCP協(xié)議的,所以在客戶端要使用Socket類,在服務(wù)器端要使用ServerSocket類;②由于基于TCP協(xié)議的通信,所以客戶端和接收端都要遵守幾個關(guān)鍵步驟;③本案例是上傳圖片,所以需要IO流來實現(xiàn)圖片的讀取和寫入,并且是在客戶端讀取圖片文件,在服務(wù)器端寫入圖片文件;④本項目是對案例11-8的改進,特別是在服務(wù)器端,需要開啟多線程來分別響應(yīng)不同客戶端上傳圖片的請求?!禞AVA程序設(shè)計》課程11.3TCP程序設(shè)計importjav

溫馨提示

  • 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)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論