




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
《JAVA程序設(shè)計(jì)》課程1、網(wǎng)絡(luò)的概念和網(wǎng)絡(luò)模型
主要內(nèi)容2、IP地址和端口號(hào)3、UDP和TCP通信協(xié)議Java程序設(shè)計(jì)4、基于UDP協(xié)議的SOCKET通信《JAVA程序設(shè)計(jì)》課程5、基于TCP協(xié)議的SOCKET通信
主要內(nèi)容6、URL、URLConnetion和HttpURLConnectionJava程序設(shè)計(jì)1.能了解OSI網(wǎng)絡(luò)模型和TCP/IP網(wǎng)絡(luò)模型的通信機(jī)制和過(guò)程《JAVA程序設(shè)計(jì)》課程
學(xué)習(xí)目標(biāo)2.能正確理解端口號(hào)的重要性,理解端口號(hào)和進(jìn)程之間的關(guān)系3.能正確運(yùn)用InetAddress類獲取主機(jī)的IP地址和域名4.能理解UDP協(xié)議和TCP在通訊時(shí)的差別5.能正確分析和編程實(shí)現(xiàn)基于UDP協(xié)議和TCP協(xié)議的SOCKET編程6.能運(yùn)用URL、URLConnetion和HttpURLConnection實(shí)現(xiàn)簡(jiǎn)單的編程11.1.1項(xiàng)目(11-1)描述《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念在聯(lián)網(wǎng)的情況下,獲取主機(jī)名為“”的IP地址列表。11.1.2項(xiàng)目知識(shí)準(zhǔn)備《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念(1)Client-Server體系構(gòu)架設(shè)想你去一家餐館,侍應(yīng)生送上菜單,在看過(guò)了充滿異國(guó)情調(diào)的菜式后,你點(diǎn)了一份匹薩。幾分鐘后,匹薩送來(lái),上面涂滿了熱乳酪和其他你所想要的一切,你開始吃起來(lái)。你不知道也從不想知道侍應(yīng)生從哪兒端來(lái)這盤匹薩、它是怎么做出來(lái)的、其中的配料又是怎么弄到的。在上例中,所涉及的實(shí)體包括-------美味口的匹薩、提供服務(wù)的侍應(yīng)生、制作匹薩的廚房、當(dāng)然還有你,你是購(gòu)買匹薩的顧客或客戶。匹薩的制作過(guò)程,對(duì)于你來(lái)說(shuō),完全是被封裝的。你的菜單在廚房進(jìn)行處理,然后由侍應(yīng)生把匹薩端給你在上面所看到的就是一個(gè)客戶/服務(wù)器體系。其中,客戶向服務(wù)端下單或提出請(qǐng)求,服務(wù)器處理客戶的請(qǐng)求。在客戶/服務(wù)器體系中,客戶和服務(wù)器之間的通信是一個(gè)極為重要的組成部分,一般是能通過(guò)網(wǎng)絡(luò)完成的。客戶/服務(wù)器體系是應(yīng)用程序的一種開發(fā)構(gòu)架,這種構(gòu)架在設(shè)計(jì)上把數(shù)據(jù)的表示與其內(nèi)部處理和存儲(chǔ)分開。在這種體系中,客戶請(qǐng)求服務(wù),服務(wù)器提供服務(wù),客戶發(fā)出請(qǐng)求經(jīng)由網(wǎng)絡(luò)發(fā)送給服務(wù)器,服務(wù)器的處理過(guò)程對(duì)于客戶來(lái)說(shuō)是不可見(jiàn)的,一個(gè)服務(wù)器可為多個(gè)客戶服務(wù)。11.1.2項(xiàng)目知識(shí)準(zhǔn)備服務(wù)端和客戶端數(shù)據(jù)傳輸?shù)姆绞饺鐖D11.1所示《JAVA程序設(shè)計(jì)》課程
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è)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念TCP/IP為Internet上所使用的數(shù)據(jù)傳輸協(xié)議(protocol),TCP為TransmissionControlProtocol的縮寫,是傳輸控制協(xié)議;而IP為InternetProtocol的縮寫,是網(wǎng)絡(luò)互聯(lián)協(xié)議。所謂傳輸協(xié)議是指計(jì)算機(jī)和計(jì)算機(jī)溝通的語(yǔ)言。TCP/IP實(shí)際上是一組協(xié)議,包括多個(gè)具有不同功能且互為關(guān)聯(lián)的協(xié)議。TCP/IP是多個(gè)獨(dú)立定義的協(xié)議集合,因此也被稱為TCP/IP協(xié)議簇。TCP/IP協(xié)議模型從更實(shí)用的角度出發(fā),形成了高效的四層體系結(jié)構(gòu),即網(wǎng)絡(luò)接口層、IP層、傳輸層和應(yīng)用層。TCP/IP的分層結(jié)構(gòu)和OSI參考模型的對(duì)應(yīng)關(guān)系如圖11.2所示:《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念OSI模型TCP/IP模型應(yīng)用層
應(yīng)用層表示層會(huì)話層傳輸層傳輸層網(wǎng)絡(luò)層IP層數(shù)據(jù)鏈路層網(wǎng)絡(luò)接口層物理層(3)IP地址(InternetProtocol)《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念在互聯(lián)網(wǎng)上的每一臺(tái)計(jì)算機(jī)都有一個(gè)唯一表示自己的標(biāo)記,這個(gè)標(biāo)記就是IP地址,在windows操作系統(tǒng)中,用戶可以通過(guò)圖11.3所示的“Internet協(xié)議屬性”窗口來(lái)設(shè)置計(jì)算機(jī)的IP地址。IP地址使用32位長(zhǎng)度二進(jìn)制數(shù)據(jù)表示,一般在實(shí)際中看到的大部分IP地址都是以十進(jìn)制的數(shù)據(jù)形式表示的,比如“00”等。IP地址的格式:IP地址=網(wǎng)絡(luò)地址+主機(jī)地址。其中網(wǎng)絡(luò)地址,也稱網(wǎng)絡(luò)號(hào):用戶識(shí)別主機(jī)所在的網(wǎng)絡(luò);主機(jī)地址,也稱主機(jī)號(hào):用戶識(shí)別該網(wǎng)絡(luò)中的主機(jī)。IP地址中的掩碼的功能主要是區(qū)分網(wǎng)絡(luò)號(hào)和主機(jī)號(hào)。《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念圖11.3Internet協(xié)議屬性窗口《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念在實(shí)際中可以使用表示本機(jī)地址,或者使用localhost也代表本機(jī)。由于IP地址不方便記憶,也可以使用域名來(lái)表示IP地址。域名和IP地址之間是有映射關(guān)系的,專門用于解析域名與IP地址之間映射關(guān)系的服務(wù)器,稱作DNS服務(wù)器。(4)端口《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念TCP與UDP都采用了應(yīng)用程序接口處的端口(port)與上層的應(yīng)用進(jìn)程進(jìn)行通信。端口是一個(gè)16位的地址,并用端口號(hào)進(jìn)行標(biāo)識(shí)。端口號(hào)為兩類。一類是專門分配給一些最常用的應(yīng)用層程序,被稱為熟知端口,數(shù)值范圍為1-1024。另一類是一般的端口號(hào),用來(lái)隨時(shí)分配給請(qǐng)求通信的客戶進(jìn)程。通常一臺(tái)主機(jī)上總是有很多個(gè)進(jìn)程需要網(wǎng)絡(luò)資源進(jìn)行網(wǎng)絡(luò)通信。網(wǎng)絡(luò)通信的對(duì)象準(zhǔn)確地講不是主機(jī),而應(yīng)該是主機(jī)中運(yùn)行的進(jìn)程。這時(shí)候光有主機(jī)名或IP地址來(lái)標(biāo)識(shí)數(shù)量較多的進(jìn)程是不夠的。端口號(hào)就是為了在一臺(tái)主機(jī)上提供更多的網(wǎng)絡(luò)資源而采取的一種手段,也是TCP層提供的一種機(jī)制。只有通過(guò)主機(jī)名或IP地址和端口號(hào)的組合才能惟一確定網(wǎng)絡(luò)通信中的對(duì)象------進(jìn)程。(5)InetAddress類《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念I(lǐng)netAddress的實(shí)例對(duì)象包含以數(shù)字形式保存的IP地址,同時(shí)還可能包含主機(jī)名。InetAddress類也提供了將主機(jī)名解析為IP地址(或反之)的方法。InetAddress的構(gòu)造函數(shù)不是公開的(public),所以需要通過(guò)它提供的靜態(tài)方法來(lái)獲取,有以下幾個(gè)常用的方法:staticInetAddress[]getAllByName(Stringhost)staticInetAddressgetByAddress(byte[]addr)staticInetAddressgetByAddress(Stringhost,byte[]addr)staticInetAddressgetByName(Stringhost)staticInetAddressgetLocalHost()《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念在這些靜態(tài)方法中,最為常用的應(yīng)該是getByName(Stringhost)方法,只需要傳入目標(biāo)主機(jī)的名字,InetAddress會(huì)嘗試做連接DNS服務(wù)器,并且獲取IP地址的操作。提醒:我們假設(shè)以下的代碼,都是默認(rèn)導(dǎo)入了中的包,在程序的開頭加上import.*,否則需要指定類的全名.InetAddress。提醒:InetAddressaddress=InetAddress.getByName("");注意到這些方法可能會(huì)拋出的異常。如果安全管理器不允許訪問(wèn)DNS服務(wù)器或禁止網(wǎng)絡(luò)連接,SecurityException會(huì)拋出,如果找不到對(duì)應(yīng)主機(jī)的IP地址,或者發(fā)生其他網(wǎng)絡(luò)I/O錯(cuò)誤,這些方法會(huì)拋出UnknowHostException。《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念所以獲取IP的地址的代碼格式如下所示:try{InetAddressaddress=InetAddress.getByName("");System.out.println(address);}catch(UnknownHostExceptione){e.printStackTrace();}《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念案例11-1:獲取本機(jī)的IP地址和域名import.InetAddress;import.UnknownHostException;publicclassLocalInetAddressTest{ //測(cè)試InetAddress類 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddressaddr=InetAddress.getLocalHost();//獲取本機(jī)的對(duì)應(yīng)的InetAddress對(duì)象《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念Stringip=addr.getHostAddress();//獲取字符串形式的IP地址 StringhostName=addr.getHostName();//獲取域名 System.out.println("本機(jī)IP="+ip+"----->本機(jī)域名="+hostName); }}《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念案例11-2:通過(guò)IP地址獲取InetAddress對(duì)象并輸出相應(yīng)的IP地址和域名import.InetAddress;import.UnknownHostException;publicclassInetAddressTestByIP{ //測(cè)試InetAddress類 publicstaticvoidmain(String[]args)throwsUnknownHostException{ InetAddressaddr=InetAddress.getByName("7");//通過(guò)IP地址獲取InetAddress對(duì)象 Stringip=addr.getHostAddress();//獲取字符串形式的IP地址 StringhostName=addr.getHostName();//獲取域名 System.out.println("IP="+ip+"----->域名為="+hostName); }}案例11-3:獲取域名為“”的主機(jī)對(duì)應(yīng)的IP列表《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念提醒:若要通過(guò)域名獲取對(duì)應(yīng)該域名的所有的映射IP地址,可以通過(guò)方法getAllByName(“主機(jī)域名”)實(shí)現(xiàn)。代碼如下所示:import.InetAddress;import.UnknownHostException;publicclassBaiDuInetAddressTest{ //測(cè)試的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:獲取域名為“”的主機(jī)對(duì)應(yīng)的IP列表提醒:若要通過(guò)域名獲取對(duì)應(yīng)該域名的所有的映射IP地址,可以通過(guò)方法getAllByName(“主機(jī)域名”)實(shí)現(xiàn)。代碼如下所示:import.InetAddress;import.UnknownHostException;publicclassBaiDuInetAddressTest{ //測(cè)試的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è)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念運(yùn)行結(jié)果如圖11.4所示圖11.4域名為“”的主機(jī)IP列表11.1.3項(xiàng)目實(shí)施《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念(1)分析通過(guò)分析題目可以得出以下信息:①已知條件是主機(jī)域名為“”;②目標(biāo)是輸出該域名對(duì)應(yīng)的IP列表,要想獲取IP列表則需要使用方法getAllByName();③由于是操作InetAddress類,需要進(jìn)行域名解析操作,所以異常聲明或異常捕獲是必要的。(2)編碼:《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念通過(guò)以上分析我們可以編寫以下代碼實(shí)現(xiàn)功能:import.InetAddress;import.UnknownHostException;publicclassBaiDuInetAddressTest{ //測(cè)試的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)試運(yùn)行,顯示結(jié)果《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念該程序的運(yùn)行結(jié)果如圖11.5所示:圖11.5“”域名對(duì)應(yīng)的IP列表11.1.4能力拓展《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念(1)選擇題①TCP協(xié)議棧的四層結(jié)構(gòu)中不包括(D)A.應(yīng)用層B.傳輸層C.網(wǎng)絡(luò)層D.會(huì)話層②獲取本機(jī)地址可以使用下面哪個(gè)方法(B)A.getHostName()B.getLocalHost()C.getByName()D.getHostAddress()
(2)填空題①目前最廣泛使用的網(wǎng)絡(luò)協(xié)議是Internet上使用的(TCP/IP)協(xié)議②套接字是一個(gè)特定機(jī)器上被編號(hào)的(端口),系統(tǒng)可用的端口號(hào)是(1-1024),用戶可用的端口號(hào)是(1025-65535)③通過(guò)域名獲取IP列表使用的方法是(getByAllName())(3)編程《JAVA程序設(shè)計(jì)》課程
11.1網(wǎng)絡(luò)編程的基本概念①編程實(shí)現(xiàn)本課中的案例11-1至案例11-3的功能,并運(yùn)行測(cè)試。②編程實(shí)現(xiàn)獲取“”的IP列表,并運(yùn)行測(cè)試。③編程實(shí)現(xiàn)本節(jié)課中的項(xiàng)目11-1中的功能,并運(yùn)行測(cè)試。11.2.1項(xiàng)目(11-2)描述《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)使用UDP協(xié)議實(shí)現(xiàn)某網(wǎng)段的群聊功能。要求從鍵盤打字,直到某人輸入“over”表示他退出聊天室;其他人可以繼續(xù)聊。11.2.2項(xiàng)目知識(shí)準(zhǔn)備《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)(1)UDP與TCP協(xié)議UDP在傳送數(shù)據(jù)之前,不需要建立連接,同時(shí),遠(yuǎn)程主機(jī)收到UDP數(shù)據(jù)包后,不需要返回任何響應(yīng)。TCP提供面向連接的服務(wù)。TCP不支持廣播或多播服務(wù)。由于TCP要提供運(yùn)輸服務(wù),因此TCP不可避免地增加了許多開銷,如應(yīng)答、流量控制、定時(shí)器以及連接管理等。這樣既增加了協(xié)議頭,也占用了更多的CPU時(shí)間。①IP協(xié)議IP協(xié)議用于管理客戶端和服務(wù)端之間的報(bào)文傳送。IP協(xié)議是所有Internet協(xié)議的基石,IP協(xié)議是一個(gè)面向包的協(xié)議,是無(wú)連接的。IP協(xié)議已經(jīng)成為世界上最重要國(guó)際協(xié)議。《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)(1)UDP與TCP協(xié)議UDP在傳送數(shù)據(jù)之前,不需要建立連接,同時(shí),遠(yuǎn)程主機(jī)收到UDP數(shù)據(jù)包后,不需要返回任何響應(yīng)。TCP提供面向連接的服務(wù)。TCP不支持廣播或多播服務(wù)。由于TCP要提供運(yùn)輸服務(wù),因此TCP不可避免地增加了許多開銷,如應(yīng)答、流量控制、定時(shí)器以及連接管理等。這樣既增加了協(xié)議頭,也占用了更多的CPU時(shí)間。①IP協(xié)議IP協(xié)議用于管理客戶端和服務(wù)端之間的報(bào)文傳送。IP協(xié)議是所有Internet協(xié)議的基石,IP協(xié)議是一個(gè)面向包的協(xié)議,是無(wú)連接的。IP協(xié)議已經(jīng)成為世界上最重要國(guó)際協(xié)議。③TCP協(xié)議TCP(TransmissionControlProtocol)即傳輸控制協(xié)議,是一個(gè)面向連接的協(xié)議,它提供雙向的、可靠的、有流量控制的字節(jié)流的服務(wù)。字節(jié)流服務(wù)的意思是:在一個(gè)TCP連接中,源節(jié)點(diǎn)發(fā)送一連串的字節(jié)給目標(biāo)節(jié)點(diǎn)《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)TCP協(xié)議有幾項(xiàng)特點(diǎn):<1>確認(rèn)回應(yīng)當(dāng)甲計(jì)算機(jī)傳送數(shù)據(jù)到乙計(jì)算機(jī)時(shí),會(huì)等待乙計(jì)算機(jī)返回確認(rèn)后才會(huì)再傳送下一筆數(shù)據(jù)。當(dāng)一段時(shí)間內(nèi)沒(méi)有收到乙計(jì)算機(jī)的確認(rèn)回應(yīng),甲計(jì)算機(jī)會(huì)試著再傳送一次,如果傳送了很多次都沒(méi)有回應(yīng),就表示鏈接可能斷了。此特征可以很容易地知道網(wǎng)絡(luò)鏈接的狀況。<2>數(shù)據(jù)包序號(hào)面向連接協(xié)議在傳送數(shù)據(jù)時(shí),會(huì)把數(shù)據(jù)切成固定大小的數(shù)據(jù)包(packet),然后在每個(gè)數(shù)據(jù)包上加上序號(hào)。這樣的好處是接收端可以檢查收到的是哪些數(shù)據(jù)包、哪些數(shù)據(jù)包重復(fù)等。<3>流量控制有了<1>和<2>兩項(xiàng)特征,就可以控制傳輸?shù)牧髁俊?/p>
《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)案例11-4:設(shè)計(jì)一個(gè)發(fā)送、接收程序,發(fā)送端向接收端發(fā)送數(shù)據(jù)。接收端接收數(shù)據(jù),并把數(shù)據(jù)打印到控制臺(tái)中。重點(diǎn):基于UDP協(xié)議的發(fā)送端發(fā)送數(shù)據(jù)的步驟有四步:(1)建立發(fā)送端對(duì)象。(2)建立數(shù)據(jù)包(發(fā)送格式)。DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)(3)調(diào)用Socket的發(fā)送方法。(4)關(guān)閉Socket。《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassSendSocket{ /**UDP *1.建立發(fā)送端對(duì)象。 *2.建立數(shù)據(jù)包(發(fā)送格式)。
發(fā)送端代碼如下:《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)*DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport) *3.調(diào)用Socket的發(fā)送方法。 *4.關(guān)閉Socket。 *@throwsIOException */ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建Socket對(duì)象 DatagramSocketsendSocket=newDatagramSocket(20000);//此時(shí)的端口號(hào)為客戶端發(fā)送數(shù)據(jù)的端口號(hào),跟服務(wù)器端的接受數(shù)據(jù)的端口號(hào)可以不一致。《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)//2.創(chuàng)建數(shù)據(jù)包對(duì)象 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è)計(jì)》課程
11.2UDP程序設(shè)計(jì)重點(diǎn):基于UDP協(xié)議的接收端接收數(shù)據(jù)的步驟有四步:(1)建立接收端對(duì)象。(2)建立數(shù)據(jù)包(接收格式)。DatagramPacket(byte[]buf,intlength)(3)調(diào)用Socket的接收方法。(4)關(guān)閉接收端Socket。接收端代碼如下《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassReceiveSocket{ /** *1.建立接收端對(duì)象。 *2.建立數(shù)據(jù)包(發(fā)送格式)。 *DatagramPacket(byte[]buf,intlength) *3.調(diào)用Socket的接收方法。 *4.關(guān)閉接收端Socket。《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)*@throwsIOException */ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建Socket對(duì)象 DatagramSocketrecevieSocket=newDatagramSocket(10000); //2.創(chuàng)建數(shù)據(jù)包對(duì)象 byte[]data=newbyte[1024]; DatagramPacketpacket=newDatagramPacket(data,data.length); //3.發(fā)送數(shù)據(jù) recevieSocket.receive(packet);//阻塞式方法 //從包裹中取數(shù)據(jù)及其他內(nèi)容《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)InetAddressaddress=packet.getAddress();//獲取發(fā)送方的IP對(duì)象 byte[]sourceData=packet.getData();//獲取發(fā)送方的數(shù)據(jù) intlen=packet.getLength();//獲取發(fā)送發(fā)發(fā)送的數(shù)據(jù)的有效長(zhǎng)度:單位為字節(jié)數(shù) intport=packet.getPort();//獲取發(fā)送方的端口號(hào) Stringtext=newString(sourceData,0,len);//把字節(jié)數(shù)組轉(zhuǎn)換為字符串 System.out.println("接收到IP="+address.getHostAddress()+",端口號(hào)="+port+"的數(shù)據(jù)----->"+text); //4.關(guān)閉socket recevieSocket.close(); }}先運(yùn)行接收端程序,讓接收端處于等待接收狀態(tài),然后再運(yùn)行發(fā)送端程序,則在接收端就收到了發(fā)送端的數(shù)據(jù),程序運(yùn)行結(jié)果如圖11.6所示:《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)圖11.6案例11-4運(yùn)行結(jié)果圖《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)案例11-5:實(shí)現(xiàn)簡(jiǎn)單的聊天功能,即發(fā)送端從鍵盤打字,按回車鍵發(fā)送數(shù)據(jù)給接收端,接收端接收數(shù)據(jù)后,把數(shù)據(jù)輸出到控制臺(tái)中;這樣重復(fù)進(jìn)行,直到發(fā)送端發(fā)送“over”結(jié)束聊天功能。分析:本功能比案例11-4多了不停的通過(guò)鍵盤打字功能,這里要使用到IO流操作。具體發(fā)送端和接收端代碼如下所示。發(fā)送端代碼:《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassChatSendSocket{
《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)/**UDP協(xié)議 *1.建立發(fā)送端對(duì)象。 *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對(duì)象 DatagramSocketsendSocket=newDatagramSocket(20000);《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)//從鍵盤輸入數(shù)據(jù),按行來(lái)發(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ù)包對(duì)象 byte[]data=lineData.getBytes();《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)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è)計(jì)》課程
11.2UDP程序設(shè)計(jì)importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassChatReceiveSocket{ publicstaticvoidmain(String[]args)throwsIOException{//1.創(chuàng)建Socket對(duì)象DatagramSocketrecevieSocket=newDatagramSocket(10000);《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)//2.創(chuàng)建數(shù)據(jù)包對(duì)象 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對(duì)象 byte[]sourceData=packet.getData();//獲取發(fā)送方的數(shù)據(jù)《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)intlen=packet.getLength();//獲取發(fā)送發(fā)發(fā)送的數(shù)據(jù)的有效長(zhǎng)度:單位為字節(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()+"說(shuō):----->" +text); } //4.關(guān)閉socket《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)recevieSocket.close(); }}先運(yùn)行接收端程序,再運(yùn)行發(fā)送端程序,其運(yùn)行結(jié)果如圖11.7所示:《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)圖11.7案例11-5的運(yùn)行結(jié)果圖11.2.3項(xiàng)目實(shí)施《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)(1)分析通過(guò)分析題目可以得出以下信息:①假設(shè)某網(wǎng)段的廣播地址為“55”;②由于是基于UDP協(xié)議的通信,所以客戶端和接收端都要遵守四個(gè)步驟③由于是UDP協(xié)議的通信,需要DatagramSocket類和DatagramPacket類,由于有可能出現(xiàn)異常,所以異常聲明或異常捕獲是必要的;④由于需要從鍵盤輸入文本數(shù)據(jù),所以需要IO流。《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)(2)發(fā)送端代碼:通過(guò)以上分析我們可以編寫以下代碼實(shí)現(xiàn)功能發(fā)送端功能:提醒:如果要實(shí)現(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è)計(jì)》課程
11.2UDP程序設(shè)計(jì)publicclassChatSendSocket1{ /**UDP協(xié)議 *1.建立發(fā)送端對(duì)象。 *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è)計(jì)》課程
11.2UDP程序設(shè)計(jì)//1.創(chuàng)建Socket對(duì)象 DatagramSocketsendSocket=newDatagramSocket(20000); //從鍵盤輸入數(shù)據(jù),按行來(lái)發(fā)送數(shù)據(jù) InputStreamis=System.in; //把字節(jié)流轉(zhuǎn)換為字符流 InputStreamReaderisr=newInputStreamReader(is); //裝飾 BufferedReaderbr=newBufferedReader(isr); StringlineData=null; while((lineData=br.readLine())!=null){《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)//2.創(chuàng)建數(shù)據(jù)包對(duì)象 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è)計(jì)》課程
11.2UDP程序設(shè)計(jì)} //4.關(guān)閉socket sendSocket.close(); }}《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)(3)接收端代碼:接收方的代碼如下所示:importjava.io.IOException;import.DatagramPacket;import.DatagramSocket;import.InetAddress;publicclassChatReceiveSocket1{ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建Socket對(duì)象《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)DatagramSocketrecevieSocket=newDatagramSocket(10000); //2.創(chuàng)建數(shù)據(jù)包對(duì)象 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對(duì)象 byte[]sourceData=packet.getData();//獲取發(fā)送方的數(shù)據(jù) intlen=packet.getLength();//獲取發(fā)送發(fā)發(fā)送的數(shù)據(jù)的有效長(zhǎng)度:單位為字節(jié)數(shù)《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)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()+"說(shuō):----->" +text); }// 4.取消關(guān)閉socket// recevieSocket.close(); }}4)調(diào)試運(yùn)行,顯示結(jié)果該程序的運(yùn)行結(jié)果如圖11.8所示:《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)圖11.8域名為“”的主機(jī)IP列表11.2.4能力拓展《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)(1)選擇題①一個(gè)Socket由(A)唯一確定A.一個(gè)IP地址和一個(gè)端口號(hào)B.一個(gè)IP地址和一個(gè)主機(jī)名C.一個(gè)主機(jī)號(hào)和一個(gè)端口號(hào)D.一個(gè)IP地址②基于UDP協(xié)議的編程中用來(lái)表示通訊端點(diǎn)(即套接字)的類是(B)A.SocketB.DatagramSocketC.ServerSocketD.DatagramPacket(2)填空題①TCP/IP協(xié)議的兩種通信協(xié)議是(TCP)協(xié)議和(UDP)協(xié)議②常用的編程模式有客戶端/(服務(wù)器)模式和B/S模式③在JAVA中基于UDP協(xié)議編程時(shí),需要使用數(shù)據(jù)包,在JAVA中描述數(shù)據(jù)包的類是(DatagramPacket),這個(gè)類的構(gòu)造方法共有6種形式的重載,其中(4)個(gè)是發(fā)送形式的,(2)個(gè)是表示接受形式的。《JAVA程序設(shè)計(jì)》課程
11.2UDP程序設(shè)計(jì)3)編程①編程實(shí)現(xiàn)本課中的案例11-4至案例11-5的編碼。②實(shí)現(xiàn)本節(jié)課程中項(xiàng)目11-2的功能,并運(yùn)行測(cè)試。11.3.1項(xiàng)目(11-3)描述《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)使用TCP協(xié)議實(shí)現(xiàn)一個(gè)圖片上傳服務(wù)器功能,即各個(gè)客戶端使用多線程技術(shù)可以向一個(gè)IP為7的服務(wù)器上上傳圖片,服務(wù)器接收上傳的圖片并將圖片保存到服務(wù)器的本地文件。11.3.2項(xiàng)目知識(shí)準(zhǔn)備《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)TCP(TransmissionControlProtocol)即傳輸控制協(xié)議,是一個(gè)面向連接的協(xié)議,它提供雙向的、可靠的、有流量控制的字節(jié)流的服務(wù)。在JAVA中使用Socket完成TCP程序的設(shè)計(jì),使用此類可以方便地建立可靠的、雙向的、持續(xù)的、點(diǎn)對(duì)點(diǎn)的通訊連接。在Socket的程序開發(fā)中,服務(wù)器端使用ServerSocket等待客戶端的連接,對(duì)于JAVA的網(wǎng)絡(luò)程序來(lái)講,每一個(gè)客戶端都要使用一個(gè)Socket對(duì)象表示。如圖11.9所示:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)圖11.9基于TCP協(xié)議的客戶端和服務(wù)器端的通訊模型Client的SocketAccept服務(wù)器端的ServerSocketClient的Socket(2)基于TCP的客戶端套接字Socket《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)Socket:套接字,相當(dāng)于插到插線板上的插頭,基于TCP實(shí)現(xiàn)網(wǎng)絡(luò)通信。一個(gè)socket是兩臺(tái)機(jī)器通信的端點(diǎn)。①套接字能執(zhí)行的基本操作主要有以下7種:<1>連接到遠(yuǎn)程機(jī)器;<2>綁定到端口;<3>接收從遠(yuǎn)程機(jī)器來(lái)的連接請(qǐng)求;<4>監(jiān)聽(tīng)到達(dá)的數(shù)據(jù);<5>發(fā)送數(shù)據(jù);<6>接收數(shù)據(jù);《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)<7>關(guān)閉連接;②Socket類主要用到兩個(gè)構(gòu)造方法:publicSocket(InetAddress
address,int
port)throwsIOException:創(chuàng)建一個(gè)流套接字并將其連接到指定IP地址的指定端口號(hào)。參數(shù):address-IP地址。port-端口號(hào)。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)拋出:UnknownHostException-如果無(wú)法確定主機(jī)的IP地址。IOException-如果創(chuàng)建套接字時(shí)發(fā)生I/O錯(cuò)誤。Socket對(duì)象常用到的方法如下:③常見(jiàn)方法publicInetAddressgetInetAddress():返回套接字連接的地址。返回:此套接字連接到的遠(yuǎn)程IP地址;如果套接字是未連接的,則返回null。publicintgetPort():返回此套接字連接到的遠(yuǎn)程端口。返回:此套接字連接到的遠(yuǎn)程端口號(hào);如果尚未連接套接字,則返回0。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)publicintgetLocalPort():返回此套接字綁定到的本地端口。返回:此套接字綁定到的本地端口號(hào);如果尚未綁定套接字,則返回-1。publicInetAddressgetLocalAddress():獲取套接字綁定的本地地址。返回:將套接字綁定到的本地地址;如果尚未綁定套接字,則返回InetAddress.anyLocalAddress()。publicInetAddressgetInetAddress()返回套接字連接的地址。返回:此套接字連接到的遠(yuǎn)程IP地址;如果套接字是未連接的,則返回null。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)publicInputStreamgetInputStream()throwsIOException返回此套接字的輸入流。publicOutputStreamgetOutputStream()throwsIOException返回此套接字的輸出流。publicvoidclose()throwsIOException關(guān)閉此套接字。publicStringtoString()將此套接字轉(zhuǎn)換為String。(3)基于TCP的服務(wù)器端套接字ServerSocket類《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)在客戶端-服務(wù)器的網(wǎng)絡(luò)模型中,利用Socket我們可以輕松開發(fā)一個(gè)客戶端程序,同樣我們利用ServerSocket可以開發(fā)服務(wù)器程序。ServerSocket:服務(wù)器套接字,相當(dāng)于插線板。基于TCP實(shí)現(xiàn)網(wǎng)絡(luò)通信。一個(gè)服務(wù)器socket等待網(wǎng)絡(luò)上來(lái)的請(qǐng)求。它執(zhí)行某些基于請(qǐng)求的操作,然后可能返回一個(gè)結(jié)果給請(qǐng)求者。①ServerSocket工作流程<1>在指定的監(jiān)聽(tīng)端口創(chuàng)建一個(gè)ServerSocket對(duì)象。<2>ServerSocket對(duì)象調(diào)用accept()方法在指定的端口監(jiān)聽(tīng)到來(lái)的連接。accept()阻塞當(dāng)前Java線程,直到收到客戶端連接請(qǐng)求,accept()方法返回連接客戶端與服務(wù)器的Socket對(duì)象。<3>調(diào)用getInputStream()方法和getOutputStream()方法獲得Socket對(duì)象的輸入和輸出流。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)<4>服務(wù)器與客戶端根據(jù)一定的協(xié)議交互數(shù)據(jù),直到一端請(qǐng)求關(guān)閉連接。<5>服務(wù)器與客戶端關(guān)閉連接<6>服務(wù)器回到第2步,繼續(xù)監(jiān)聽(tīng)下一次的連接。而客戶端則運(yùn)行結(jié)束。②ServerSocket類的構(gòu)建器有:ServerSocket():創(chuàng)建非綁定服務(wù)器套接字。ServerSocket(int
port):創(chuàng)建綁定到特定端口的服務(wù)器套接字。ServerSocket(int
port,int
backlog):《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)創(chuàng)建服務(wù)器套接字并將其綁定到指定的本地端口號(hào)。ServerSocket(int
port,int
backlog,InetAddress
bindAddr):使用指定的端口、偵聽(tīng)backlog和要綁定到的本地IP地址創(chuàng)建服務(wù)器。③ServerSocket類主要方法accept():偵聽(tīng)并接受到此套接字的連接。bind(SocketAddress
endpoint):將ServerSocket綁定到特定地址(IP地址和端口號(hào))。bind(SocketAddress
endpoint,int
backlog):將ServerSocket綁定到特定地址(IP地址和端口號(hào))。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)close():關(guān)閉此套接字。getChannel():返回與此套接字關(guān)聯(lián)的唯一ServerSocketChannel對(duì)象(如果有)。getInetAddress():返回此服務(wù)器套接字的本地地址。getLocalPort():
返回此套接字在其上偵聽(tīng)的端口。getLocalSocketAddress():返回此套接字綁定的端點(diǎn)的地址,如果尚未綁定則返回null。getReceiveBufferSize():《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)獲取此ServerSocket的SO_RCVBUF選項(xiàng)的值,該值是將用于從此ServerSocket接受的套接字的建議緩沖區(qū)大小。getReuseAddress():測(cè)試是否啟用SO_REUSEADDR。getSoTimeout():獲取SO_TIMEOUT的設(shè)置。implAccept(Socket
s):ServerSocket的子類使用此方法重寫accept()以返回它們自己的套接字子類。isBound():返回ServerSocket的綁定狀態(tài)。isClosed():返回ServerSocket的關(guān)閉狀態(tài)《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)rformancePrefsetPeerences(intconnectionTime,intlatency,intbandwidth):設(shè)置此ServerSocket的性能首選項(xiàng)。setReceiveBufferSize(int
size):為從此ServerSocket接受的套接字的SO_RCVBUF選項(xiàng)設(shè)置默認(rèn)建議值。setReuseAddress(booleanon):?jiǎn)⒂?禁用SO_REUSEADDR套接字選項(xiàng)。setSoTimeout(int
timeout)通過(guò)指定超時(shí)值,以毫秒為單位。④服務(wù)器與客戶機(jī)之間的通信過(guò)程如下圖11.10所示《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)圖11.10:服務(wù)器與客戶機(jī)的通信《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)1.客戶端發(fā)出連接Client1socketClient2socket為Client1創(chuàng)建的Socket為Client2創(chuàng)建的SocketServerClient2.服務(wù)器接受請(qǐng)求并創(chuàng)建新的Socket3.兩個(gè)Socket之間建立專線連接案例11-6:設(shè)計(jì)一個(gè)發(fā)送、接收程序,發(fā)送端向接收端發(fā)送數(shù)據(jù)。接收端接收數(shù)據(jù),并把數(shù)據(jù)打印到控制臺(tái)中。發(fā)送端主要操作步驟:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)重點(diǎn):基于TCP協(xié)議的客戶端發(fā)送數(shù)據(jù)的步驟有五步:(1)建立客戶端對(duì)象,明確服務(wù)器的IP和端口號(hào);(2)若建立連接成功,則可以通過(guò)getOutputStream()獲取輸出流,也可以通過(guò)getInputStream()獲取輸入流;(3)使用輸出流向服務(wù)器端輸出數(shù)據(jù);(4)使用輸入流獲取服務(wù)器端返回的數(shù)據(jù);(5)關(guān)閉Socket。在本案例中是向服務(wù)器發(fā)送數(shù)據(jù),并不接收服務(wù)器的數(shù)據(jù),所以主要使用到了(1)、(2)、(3)、(5)四個(gè)步驟。客戶端代碼如下:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)importjava.io.IOException;importjava.io.OutputStream;import.Socket;import.UnknownHostException;publicclassClientDemo{ /** *客戶端發(fā)數(shù)據(jù)到服務(wù)端 *Tcp傳輸,客戶端建立的過(guò)程。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)*1.創(chuàng)建tcp客戶端socket服務(wù)。使用的是Socket對(duì)象。 * 建議該對(duì)象創(chuàng)建時(shí)就明確目的地。要連接的主機(jī)。 *2.如果連接建立成功,說(shuō)明數(shù)據(jù)傳輸通道已建立。 * 可以通過(guò)getOutputStream(),和getInputStream()來(lái)獲取兩個(gè)字節(jié)流。 *3.使用輸出流,將數(shù)據(jù)寫出。 *4.關(guān)閉資源。 */ publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{ //創(chuàng)建客戶端socket服務(wù)。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)Socketsocket=newSocket("7",10002); //獲取socket流中的輸出流。 OutputStreamout=socket.getOutputStream(); //使用輸出流將指定的數(shù)據(jù)寫出去。 out.write("你好,這是來(lái)自客戶端的數(shù)據(jù)".getBytes()); //關(guān)閉資源。 socket.close(); }}服務(wù)器端編程的主要操作步驟:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)重點(diǎn):基于TCP協(xié)議的服務(wù)器端接收數(shù)據(jù)的步驟有六步:(1)建立接服務(wù)器端的ServerSocket對(duì)象,服務(wù)器端Socket必須對(duì)外提供一個(gè)端口,否則客戶端無(wú)法連接;(2)獲取客戶端的Socket對(duì)象;(3)通過(guò)getOutputStream()來(lái)獲取服務(wù)器端的輸出流,和getInputStream()來(lái)獲取服務(wù)器端的輸入流;(4)通過(guò)輸入流獲取客戶端的數(shù)據(jù);(5)通過(guò)輸出流向客戶端發(fā)送數(shù)據(jù);(6)關(guān)閉客戶端的Socket對(duì)象和服務(wù)器端的ServerSocket對(duì)象。在本案例中只是接收客戶端的數(shù)據(jù),并不向客戶端發(fā)送數(shù)據(jù),所以需要上述的(1)、(2)、(3)、(4)、(6)接收端代碼如下《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)importjava.io.IOException;importjava.io.InputStream;import.ServerSocket;import.Socket;publicclassServerDemo{ //服務(wù)端接收客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),并打印在控制臺(tái)上。 /* *建立tcp服務(wù)端的思路:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)*1,創(chuàng)建服務(wù)端的端點(diǎn)ServerSocket對(duì)象。 *2,服務(wù)器端ServerSocket對(duì)象必須對(duì)外提供一個(gè)端口,否則客戶端無(wú)法連接。 *3,獲取連接過(guò)來(lái)的客戶端對(duì)象。 *4,通過(guò)客戶端對(duì)象獲取socket流讀取客戶端發(fā)來(lái)的數(shù)據(jù) * 并打印在控制臺(tái)上。 *5,關(guān)閉資源。關(guān)客戶端,關(guān)服務(wù)器端。 */ publicstaticvoidmain(String[]args)throwsIOException{//1.創(chuàng)建服務(wù)端對(duì)象。 ServerSocketss=newServerSocket(10002);《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)//2.獲取連接過(guò)來(lái)的客戶端對(duì)象。 Sockets=ss.accept();//阻塞式. Stringip=s.getInetAddress().getHostAddress(); //3.通過(guò)socket對(duì)象獲取輸入流,要讀取客戶端發(fā)來(lái)的數(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è)計(jì)》課程11.3TCP程序設(shè)計(jì)s.close(); ss.close(); }}先運(yùn)行服務(wù)器端程序,服務(wù)器端的程序處于等待接收狀態(tài),然后再運(yùn)行客戶端程序,則服務(wù)器端的程序就收到了客戶端的數(shù)據(jù),程序運(yùn)行結(jié)果如圖11.11所示:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)圖11.11案例11-6運(yùn)行結(jié)果圖案例11-7:使用TCP協(xié)議實(shí)現(xiàn)客戶端和服務(wù)器端相互發(fā)數(shù)據(jù)功能。分析:本案例功能比案例11-6多了部分功能,在客戶端多了接收服務(wù)器端返回?cái)?shù)據(jù)的功能,在服務(wù)器端多了向客戶端發(fā)送數(shù)據(jù)的功能。客戶端代碼如下:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;import.Socket;import.UnknownHostException;publicclassClientDemo2{ publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)//1.創(chuàng)建客戶端的Socket對(duì)象 Socketsocket=newSocket("7",10002); //2.獲取客戶端的輸出流out OutputStreamout=socket.getOutputStream(); //3.通過(guò)輸出流向服務(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è)計(jì)》課程11.3TCP程序設(shè)計(jì)intlen=in.read(buf); Stringtext=newString(buf,0,len); System.out.println(text); //5.關(guān)閉資源。 socket.close(); }}服務(wù)器端程序代碼如下:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;import.ServerSocket;import.Socket;publicclassServerDemo2{ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建服務(wù)端對(duì)象。 ServerSocketss=newServerSocket(10002);《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)//2.獲取連接過(guò)來(lái)的客戶端對(duì)象。 Sockets=ss.accept(); Stringip=s.getInetAddress().getHostAddress(); //3.通過(guò)socket對(duì)象獲取輸入流, InputStreamin=s.getInputStream(); //4.讀取客戶端發(fā)來(lái)的數(shù)據(jù) byte[]buf=newbyte[1024];intlen=in.read(buf); Stringtext=newString(buf,0,len); System.out.println(ip+":"+text);《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)//5.使用客戶端socket對(duì)象的輸出流給客戶端返回?cái)?shù)據(jù) OutputStreamout=s.getOutputStream(); out.write("我是服務(wù)器端,我收到你發(fā)送的數(shù)據(jù)".getBytes()); //6.關(guān)閉socket s.close();//s關(guān)閉時(shí)同時(shí)關(guān)閉了in和out兩個(gè)流 ss.close(); }}《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)先運(yùn)行服務(wù)器端程序,再運(yùn)行客戶端程序,其運(yùn)行結(jié)果如圖11.12所示:提醒:本例中客戶端sokect.close()關(guān)閉了客戶端的輸入流和輸出流,同樣在服務(wù)器端s.close()也關(guān)閉了服務(wù)器端的輸入流和輸出流。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)圖11.12案例11-7的運(yùn)行結(jié)果圖案例11-8:使用TCP協(xié)議實(shí)現(xiàn)客戶端向服務(wù)器端上傳圖片功能。分析:本案例功能比較簡(jiǎn)單即在案例11-7的基礎(chǔ)上改進(jìn)即可,因?yàn)榘l(fā)送的不是一句話,而是一個(gè)圖片文件,這里要使用IO流來(lái)實(shí)現(xiàn)輸入和輸出文件操作。客戶端代碼如下:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)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è)計(jì)》課程11.3TCP程序設(shè)計(jì)服務(wù)器端程序代碼如下:提醒:本例中客戶端程序中的s.shutdownOutput();語(yǔ)句比較重要,它的意思是告訴服務(wù)端:客戶端的數(shù)據(jù)發(fā)送完畢。讓服務(wù)端停止讀取。importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)import.ServerSocket;import.Socket;publicclassUploadPicServer{ publicstaticvoidmain(String[]args)throwsIOException{ //1.創(chuàng)建tcp的socket服務(wù)端。 ServerSocketss=newServerSocket(10003); //2.通過(guò)循環(huán),依次接收客戶端發(fā)送的數(shù)據(jù) while(true){ Sockets=ss.accept();《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)Stringip=s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); try{ //3.獲取輸入流 InputStreamin=s.getInputStream(); //4.將讀取到數(shù)據(jù)存儲(chǔ)到一個(gè)文件中。 Filedir=newFile("d:\\pic");//圖片保存到服務(wù)器的d:盤的pic目錄中 if(!dir.exists()){ dir.mkdir();《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)} Filefile=newFile(dir,ip+".png");//圖片的擴(kuò)展名為png格式 FileOutputStreamfos=newFileOutputStream(file); byte[]buf=newbyte[1024]; intlen=0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } //5.獲取socket輸出流,將圖片上傳成功告之客戶端。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)OutputStreamout=s.getOutputStream(); out.write("圖片上傳成功".getBytes()); //6.關(guān)閉socket fos.close();//單獨(dú)關(guān)閉文件輸出流 s.close(); System.out.println("客戶端IP="+ip+"的客戶上傳圖片成功!"); }catch(IOExceptione){ System.out.println(e.getMessage()); } }《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)//ss.close();//服務(wù)器端一直等待接收客戶端的數(shù)據(jù),就不能關(guān)閉了 }}提醒:在本案例中使用了dir.exists(),是判斷服務(wù)器端的d盤下是否存在pic目錄,如果不存在,則創(chuàng)建該目錄。先運(yùn)行服務(wù)器端程序,再運(yùn)行客戶端程序,其運(yùn)行結(jié)果如圖11.13所示:《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)圖11.13案例11-8的運(yùn)行結(jié)果圖11.3.3項(xiàng)目實(shí)施《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)1)分析通過(guò)分析題目可以得出以下信息:①本題目是基于TCP協(xié)議的,所以在客戶端要使用Socket類,在服務(wù)器端要使用ServerSocket類;②由于基于TCP協(xié)議的通信,所以客戶端和接收端都要遵守幾個(gè)關(guān)鍵步驟;③本案例是上傳圖片,所以需要IO流來(lái)實(shí)現(xiàn)圖片的讀取和寫入,并且是在客戶端讀取圖片文件,在服務(wù)器端寫入圖片文件;④本項(xiàng)目是對(duì)案例11-8的改進(jìn),特別是在服務(wù)器端,需要開啟多線程來(lái)分別響應(yīng)不同客戶端上傳圖片的請(qǐng)求。《JAVA程序設(shè)計(jì)》課程11.3TCP程序設(shè)計(jì)importjav
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 汽車零配件質(zhì)量控制與驗(yàn)收考核試卷
- 碩士生職學(xué)融合規(guī)劃
- 吉林省公主嶺第五中學(xué)2024-2025學(xué)年高考押題金卷(全國(guó)卷Ⅲ)歷史試題試卷含解析
- 山西警官職業(yè)學(xué)院《高級(jí)日語(yǔ)聽(tīng)力》2023-2024學(xué)年第一學(xué)期期末試卷
- 山西省大同市云岡區(qū)翰林學(xué)校2024-2025學(xué)年數(shù)學(xué)四下期末學(xué)業(yè)水平測(cè)試試題含解析
- 天津美術(shù)學(xué)院《幼兒行為觀察與評(píng)價(jià)》2023-2024學(xué)年第二學(xué)期期末試卷
- 江西省奉新一中2025年普通高中高三教學(xué)質(zhì)量檢測(cè)試題(一)生物試題含解析
- 山東省濱州市濱城區(qū)三河湖鎮(zhèn)第四小學(xué)2024-2025學(xué)年小升初全真模擬數(shù)學(xué)檢測(cè)卷含解析
- 四川輕化工大學(xué)《新安醫(yī)家針灸學(xué)說(shuō)》2023-2024學(xué)年第一學(xué)期期末試卷
- 江西南昌市心遠(yuǎn)中學(xué)度重點(diǎn)中學(xué)2025年初三二診測(cè)試(化學(xué)試題理)試題含解析
- 國(guó)開2024年秋中國(guó)建筑史(本)終考任務(wù)答案
- 中華人民共和國(guó)農(nóng)村集體經(jīng)濟(jì)組織法
- 中藥學(xué)電子版教材
- GA∕T 1622-2019 法庭科學(xué) 生物檢材中沙蠶毒素、殺蟲雙、殺蟲環(huán)和殺螟丹檢驗(yàn) 氣相色譜、氣相色譜-質(zhì)譜和液相色譜-質(zhì)譜法
- 國(guó)際商事仲裁法
- 區(qū)域電力系統(tǒng)規(guī)劃設(shè)計(jì)開題報(bào)告
- 居民企業(yè)資產(chǎn)股權(quán)劃轉(zhuǎn)特殊性稅務(wù)處理申報(bào)表
- 高層建筑無(wú)地下室傾覆及滑移計(jì)算
- 有機(jī)無(wú)機(jī)復(fù)混肥生產(chǎn)職位操作規(guī)程
- ERP生產(chǎn)管理系統(tǒng)用戶手冊(cè)(共51頁(yè))
- 封條模板(A3紙)
評(píng)論
0/150
提交評(píng)論