版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
Java面向對象程序設計網(wǎng)絡編程本章內(nèi)容掌握網(wǎng)絡編程的一些基礎知識了解網(wǎng)絡編程的原理掌握基于TCP協(xié)議的網(wǎng)絡編程掌握基于udp協(xié)議的網(wǎng)絡編程任務相關知識
網(wǎng)絡編程指的就是通過網(wǎng)絡進行程序數(shù)據(jù)操作,既然是網(wǎng)絡開發(fā),那么一定就分為用戶和服務兩端,而這兩個端的開發(fā)實際上就有以下的兩種不同的架構:·
C/S(Client/Server):要開發(fā)兩套程序,一套是服務器端,另外一套是與之對應的客戶端,但是這種程序在日后進行維護的時候,是需要維護兩套程序,而且客戶端的程序更新也必須及時,此類程序安全;·
B/S(Browser/Server):要開發(fā)一套程序,只開發(fā)服務器端的,客戶端使用瀏覽器進行訪問,這種程序在日后進行程序維護的時候只需要維護服務器端即可,客戶端不需要做任何的修改,此類程序使用公共端口,包括公共協(xié)議,所以安全性很差。
如果從網(wǎng)絡的開發(fā)而言,大的分類是以上的兩類,可是從現(xiàn)在的開發(fā)來講,更多的情況是針對于B/S程序進行的開發(fā),或者可以這么理解:B/S程序的開發(fā)屬于網(wǎng)絡時代,而C/S程序的開發(fā)屬于單機時代。而對于WebService的開發(fā),實話而言,也屬于B/S結構的程序(跨平臺)。
而在日后學習Android開發(fā)的時候,如果要考慮安全性使用Socket,如果要考慮方便性,還是基于WEB的開發(fā)方便使用。而對于網(wǎng)絡的開發(fā)在Java中也分為兩種:TCP(傳輸控制協(xié)議,可靠的傳輸)、UDP(數(shù)據(jù)報協(xié)議),對于網(wǎng)絡開發(fā),本次只專注于TCP程序的實現(xiàn)。網(wǎng)絡編程基礎知識網(wǎng)絡編程的目的就是指直接或間接地通過網(wǎng)絡協(xié)議與其他計算機進行通訊。網(wǎng)絡編程中有兩個主要的問題,一個是如何準確的定位網(wǎng)絡上一臺或多臺主機,另一個就是找到主機后如何可靠高效的進行數(shù)據(jù)傳輸。在TCP/IP協(xié)議中IP層主要負責網(wǎng)絡主機的定位,數(shù)據(jù)傳輸?shù)穆酚桑蒊P地址可以唯一地確定Internet上的一臺主機。而TCP層則提供面向應用的可靠的或非可靠的數(shù)據(jù)傳輸機制。目前較為流行的網(wǎng)絡編程模型是客戶機/服務器(C/S)結構,即通信雙方一方作為服務器等待客戶提出請求并予以響應??蛻魟t在需要服務時向服務器提出申請。服務器一般作為守護進程始終運行,監(jiān)聽網(wǎng)絡端口,一旦有客戶請求,就會啟動一個服務進程來響應該客戶,同時自己繼續(xù)監(jiān)聽服務端口,使后來的客戶也能及時得到服務。網(wǎng)絡編程涉及到幾個概念:通訊協(xié)議:通訊協(xié)議:計算機網(wǎng)絡中實現(xiàn)通訊必須遵循的一些約定,這些約定被稱為通信協(xié)議。通信協(xié)議負責對傳輸速率、傳輸代碼、代碼結構、傳輸控制步驟、出錯控制等制定處理標準。網(wǎng)絡通訊協(xié)議有很多種,目前應用最廣泛的使TCP/IP協(xié)議(TransmissionControlProtocol/InternetProtocol)、UDP協(xié)議(UserDatagramProtocol)、ICMP協(xié)議(InternetControlMessageProtocol)和其他一些協(xié)議的協(xié)議組。本章涉及到TCP協(xié)議和UDP協(xié)議。TCP是傳輸控制協(xié)議,是一種面向連接的保證可靠傳輸?shù)膮f(xié)議。通過TCP協(xié)議傳輸,得到的是一個順序的無差錯的數(shù)據(jù)流??蛻舳撕头掌鞫嗣看谓?shù)據(jù)連接都要經(jīng)過“三次握手”。三次握手協(xié)議指的是在發(fā)送數(shù)據(jù)的準備階段,服務器端和客戶端之間需要進行三次交互:第一次握手:客戶端發(fā)送syn包(syn=j)到服務器,并進入SYN_SEND狀態(tài),等待服務器確認;第二次握手:服務器收到syn包,必須確認客戶的syn(ack=j+1),同時自己也發(fā)送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態(tài);第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發(fā)送確認包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務器進入ESTABLISHED狀態(tài),完成三次握手。連接建立后,客戶端和服務器就可以開始進行數(shù)據(jù)傳輸了。UDP是UserDatagramProtocol(用戶數(shù)據(jù)報協(xié)議)的簡稱,是一種無連接的、不可靠的協(xié)議,每個數(shù)據(jù)報都是一個獨立的信息,包括完整的源地址或目的地址,它在網(wǎng)絡上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內(nèi)容的正確性都是不能被保證的。但是這個協(xié)議的速度卻比較快,所以在現(xiàn)在網(wǎng)絡基礎設施越來越好的情況下,使用UDP協(xié)議的應用程序也越來越多了。IP地址表識Internet上的計算機。知道了網(wǎng)絡中某一臺主機的IP地址,就可以定位這臺計算機,通過這種地址標識,網(wǎng)絡中計算機可以相互定位和通訊,采用IPV4、IPV6兩種格式。IP地址:Port端口號是計算機輸入輸出信息的接口,端口是網(wǎng)絡通信時同一主機上的不同進程的標識,標識正在計算機上運行的進程(程序)。端口號被規(guī)定為一個16位的整數(shù)0-65535,其中,0-1023被預定義的服務通信占用,應該使用1024-65535這些端口中的某一個進行通信。每個程序監(jiān)聽本機上的一個端口套接字Socket:套接字是用來描述IP地址和端口的,可以把它看成是一個通信端點。Socket實際是傳輸層供給應用層的編程接口。Socket就是應用層與傳輸層之間的橋梁。使用Socket編程可以開發(fā)客戶機和服務器應用程序,可以在本地網(wǎng)絡上進行通信,也可通過Internet在全球范圍內(nèi)通信,Socket連接示意圖如圖10.1所示:創(chuàng)建客戶端的socket的時候,socket=newSocket(“218:198:118:108”,80);Socket連接到ip地址是218:198:118:108,服務器端口80的服務器上。同時會自動生成一個本地端口號,該端口號和服務器端口號建立一條通信鏈路。套接字是由IP地址和端口號組成的,簡單解釋一下,假設你的電腦上有兩個程序都在運行,并且都從服務器端讀取數(shù)據(jù),一個是A,一個是B,現(xiàn)在A的服務器和B的服務器同時發(fā)送來數(shù)據(jù),現(xiàn)在怎么判斷接收到的網(wǎng)絡數(shù)據(jù)是給哪一個程序使用的呢?這就是端口的作用了!每個程序監(jiān)聽本機上的一個端口,就可以從這個端口讀取數(shù)據(jù)了!這樣數(shù)據(jù)就不會混亂。本地端口號和服務器端端口號不一致。套接字Socket:(續(xù))URL:protocol://resourceName
協(xié)議名(protocol)指明獲取資源所使用的傳輸協(xié)議,如http、ftp、gopher、file等,資源名(resourceName)則應該是資源的完整地址,包括主機名、端口號、文件名或文件內(nèi)部的一個引用。例如:/
協(xié)議名://主機名/home/welcome.html
協(xié)議名://機器名+文件名:80/Gamelan/network.html#BOTTOM協(xié)議名://機器名+端口號+文件名+內(nèi)部引用網(wǎng)絡編程原理要實現(xiàn)網(wǎng)絡機器間的通訊,首先得來看看計算機系統(tǒng)網(wǎng)絡通信的基本原理,在底層層面去看,網(wǎng)絡通信需要做的就是將流從一臺計算機傳輸?shù)搅硗庖慌_計算機,基于傳輸協(xié)議和網(wǎng)絡IO來實現(xiàn),其中傳輸協(xié)議比較出名的有http、tcp、udp等等,http、tcp、udp都是在基于Socket概念上為某類應用場景而擴展出的傳輸協(xié)議,網(wǎng)絡IO,主要有bio、nio、aio三種方式,所有的分布式應用通訊都基于這個原理而實現(xiàn),只是為了應用的易用,各種語言通常都會提供一些更為貼近應用易用的應用層協(xié)議。網(wǎng)絡上的兩個程序通過一個雙向的通訊連接實現(xiàn)數(shù)據(jù)的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現(xiàn)客戶方和服務方的連接。Socket是TCP/IP協(xié)議的一個十分流行的編程界面,一個Socket由一個IP地址和一個端口號唯一確定。但是,Socket所支持的協(xié)議種類也不光TCP/IP一種,因此兩者之間是沒有必然聯(lián)系的。在Java環(huán)境下,Socket編程主要是指基于TCP/IP協(xié)議的網(wǎng)絡編程。Java網(wǎng)絡通訊原理:要實現(xiàn)網(wǎng)絡機器間的通訊,首先得來看看計算機系統(tǒng)網(wǎng)絡通信的基本原理,在底層層面去看,網(wǎng)絡通信需要做的就是將流從一臺計算機傳輸?shù)搅硗庖慌_計算機,基于傳輸協(xié)議和網(wǎng)絡IO來實現(xiàn),其中傳輸協(xié)議比較出名的有http、tcp、udp等等,http、tcp、udp都是在為某類應用場景而定義出的傳輸協(xié)議,網(wǎng)絡IO,主要有bio、nio、aio三種方式,所有的分布式應用通訊都基于這個原理而實現(xiàn),只是為了應用的易用,各種語言通常都會提供一些更為貼近應用易用的應用層協(xié)議。TCP/IP服務器端應用程序是通過Java語言中提供的ServerSocket和Socket這兩個有關網(wǎng)絡的類來實現(xiàn)的。而ServerSocket類除了建立一個Server之外,還通過accept()方法提供了隨時監(jiān)聽客戶端連接請求的功能,它的構造方法有以下兩種。ServerSocket(intport)ServerSocket(intport,intbacklog)其中port是指連接中對方的端口號,backlog則表示服務器端所能支持的最大連接數(shù)。下面的程序用來監(jiān)聽客戶端應用程序建立連接的請求,并在連接建立后向客戶端發(fā)送信息。Java中的網(wǎng)絡通信時通過Socket實現(xiàn)的,Socket分為ServerSocket和Socket兩大類,ServerSocket用于服務器端,可以通過accept方法監(jiān)聽請求,監(jiān)聽請求后返回Socket,Socket用于完成具體數(shù)據(jù)傳輸,客戶端也可以使用Socket發(fā)起請求并傳輸數(shù)據(jù)。ServerSocket的使用可以分為三步:創(chuàng)建ServerSocket。ServerSocket的構造方法有5個,其中最方便的是ServerSocket(intport),只需要一個port就可以了。調用創(chuàng)建出來的ServerSocket的accept方法進行監(jiān)聽。accept方法是阻塞方法,也就是說調用accept方法后程序會停下來等待連接請求,在接受請求之前程序將不會繼續(xù)執(zhí)行,當接收到請求后accept方法返回一個Socket。使用accept方法返回的Socket與客戶端進行通信TCP是TranferControlProtocol的簡稱,是一種面向連接的保證可靠傳輸?shù)膮f(xié)議。通過TCP協(xié)議傳輸,得到的是一個順序的無差錯的數(shù)據(jù)流。發(fā)送方和接收方的成對的兩個socket之間必須建立連接,以便在TCP協(xié)議的基礎上進行通信,當一個socket(通常都是serversocket)等待建立連接時,另一個socket可以要求進行連接,一旦這兩個socket連接起來,它們就可以進行雙向數(shù)據(jù)傳輸,雙方都可以進行發(fā)送或接收操作?;赥CP協(xié)議的網(wǎng)絡編程服務器端的步驟:1、創(chuàng)建服務器端的ServerSocket對象,綁定監(jiān)聽端口2、調用accept()方法進行偵聽客戶端的請求,等待客戶端的連接3、與客戶端建立連接以后,通過輸入流讀取客戶端發(fā)送的請求信息4、通過輸出流用來響應客戶端5、關閉輸入輸出流以及socket等相應的資源客戶端的步驟:1、創(chuàng)建socket對象,并且指明需要連接的服務器端的地址以及端口號,用來與服務器端進行連接2、連接建立后,獲取一個輸出流,通過輸出流向服務器端發(fā)送請求信息3、通過輸入流,讀取服務器端響應的信息4、關閉相應的資源相關的類介紹在Java的類庫中,URL、URLConnection、Socket、ServerSocket類都是利用TCP在網(wǎng)絡上通信的;而DatagramPacket和DatagramSocket類是使用UDP的。本章將主要講述利用TCP協(xié)議進行通信的各個類。1、URL類:.URL,是統(tǒng)一資源定位器,它是指向internet資源的指針。通過URL標識,就可以利用各種網(wǎng)絡協(xié)議來獲取遠端計算機上的資源或信息,從而方便快捷地開發(fā)Internet應用程序。格式:傳輸協(xié)議名://主機名:端口號/文件名#引用構造方法:表10.1常用方法:表10.2構造方法主要功能(spec)從String表示形成一個URL對象(context,spec)通過在指定的上下文中解析給定的規(guī)范來創(chuàng)建一個URL方法主要功能ObjectgetContent()獲取此URL的內(nèi)容intgetDefaultPort()獲取與此URL關聯(lián)協(xié)議的默認端口號StringgetFile()獲取此URL的文件名StringgetHost()獲取此URL的主機名(如適用)StringgetPath()獲取此URL的路徑部分intgetPort()獲取此URL的端口號StringgetProtocol()獲取此URL的協(xié)議名稱StringgetRef()獲取此URL的錨點(也稱為“引用”)URLConnectionopenConnection()它表示到URL所引用的遠程對象的連接InputStreamopenStream()打開與此URL,并返回一個InputStream,以便從該連接讀取【例10-1】:通過案例來掌握使用URL類獲取遠端主機上指定文件的內(nèi)容:創(chuàng)建一個參數(shù)為/index.html的URL對象,然后讀取這個對象的文件。importjava.io.*;import.URL;publicclassDemo10_01{ publicstaticvoidmain(String[]args)throwsException{ //創(chuàng)建URL對象 URLurl=newURL("/index.html"); //創(chuàng)建InputStreamReader對象 InputStreamReaderis=newInputStreamReader(url.openStream()); System.out.println("協(xié)議:"+url.getProtocol());//顯示協(xié)議名 System.out.println("主機:"+url.getHost());//顯示主機名 System.out.println("端口:"+url.getDefaultPort());//顯示與此URL關聯(lián)協(xié)議的默認端口號 System.out.println("路徑:"+url.getPath());//顯示路徑名 System.out.println("文件:"+url.getFile());//顯示文件名 //創(chuàng)建BufferedReader對象 BufferedReaderbr=newBufferedReader(is); StringinputLine; System.out.println("文件內(nèi)容:"); //按行從緩沖輸入流循環(huán)讀字符,直到讀完所有行 while((inputLine=br.readLine())!=null){ System.out.println(inputLine);//把讀取的數(shù)據(jù)輸出到屏幕上} br.close();//關閉字符輸入流}}該程序的運行結果:協(xié)議:http主機:端口:80路徑:/index.html文件:/index.html文件內(nèi)容:<!DOCTYPEhtml><!--STATUSOK--><html><head><metahttp-equiv=content-typecontent=text/html;charset=utf-8><metahttp-equiv=X-UA-Compatiblecontent=IE=Edge><metacontent=alwaysname=referrer><linkrel=stylesheettype=text/csshref=/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head>……文件內(nèi)容太多,</head>以下內(nèi)容就此省略。URLConnection抽象類URLConnection是所有類的超類,它代表應用程序和
URL
之間的通信鏈接。此類的實例可用于讀取和寫入此
URL
引用的資源。構造方法:表10.3常用方法:表10.4構造方法主要功能URLConnection(URLurl)構造與指定URL的URL連接方法主要功能ObjectgetContent()檢索此URL連接的內(nèi)容StringgetContentEncoding()返回content-encoding標題字段的值IntgetContentLength()返回content-length標題字段的值StringgetContentType()返回content-type標題字段的值URLgetURL()返回此URLConnection的URL字段的值InputStreamgetInputStream()返回從此打開的連接讀取的輸入流OutputStreamgetOutputStream()返回寫入此連接的輸出流publicvoidsetConnectTimeout(inttimeout)設定一個指定的超時值(以毫秒為單位)【例10-2】:通過案例來掌握使用URLConnection類獲取Web頁面信息功能實現(xiàn):使用URLConnection顯示網(wǎng)址/index.html的相關信息。importjava.io.*;import.URL;import.URLConnection;publicclassDemo10_02{ publicstaticvoidmain(String[]args)throwsException{ Strings; //創(chuàng)建URL對象 URLurl=newURL("/index.htm"); //定義URLConnection對象,并讓其指向給定的連接 URLConnectionuc=url.openConnection(); System.out.println("文件類型:"+uc.getContentType()); System.out.println("文件長度:"+uc.getContentLength()); System.out.println("文件內(nèi)容:"); System.out.println("--------------------------------------------"); //定義字節(jié)輸入流對象,并使其指向給定連接的輸入流 BufferedReaderis=newBufferedReader(newInputStreamReader(uc.getInputStream()));//創(chuàng)建BufferedReader對象 while((s=is.readLine())!=null){//循環(huán)讀下一個字節(jié),直到文件結束 System.out.println(s);//輸出字節(jié)對應的字符 } is.close();//關閉字節(jié)流 }}該程序的運行結果:文件類型:text/html文件長度:2381文件內(nèi)容:--------------------------------------------<!DOCTYPEhtml><!--STATUSOK--><html><head><metahttp-equiv=content-typecontent=text/html;charset=utf-8><metahttp-equiv=X-UA-Compatiblecontent=IE=Edge><metacontent=alwaysname=referrer><linkrel=stylesheettype=text/csshref=/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head>文件內(nèi)容太多,</head>以下內(nèi)容就此省略。3、InetAddress:在internet上,表示一個主機的地址有兩種方式,即域名地址(如:)和ip地址(如:10).該類正是用來表示主機地址的。InetAddress類提供將主機名解析為其IP地址(或反之)的方法。常用方法:表10.53、InetAddress:在internet上,表示一個主機的地址有兩種方式,即域名地址(如:)和ip地址(如:10).該類正是用來表示主機地址的。InetAddress類提供將主機名解析為其IP地址(或反之)的方法。常用方法:表10.5InetAddress:方法主要功能StaticInetAddressgetByAddress(byte[]addr)在給定原始ip地址的情況下,返回InetAddress對象StaticInetAddressgetByAddress(Stringhost,byte[]addr)根據(jù)提供的主機名和IP地址創(chuàng)建InetAddressStaticInetAddressgetLocalHost()返回本地主機StaticInetAddressgetByName(Stringhost)在給定主機名的情況下確定主機的ip地址Byte[]getAddress()返回此InetAddress對象的原始ip地址StringgetHostAddress()返回ip地址字符串StringgetHostName()獲取此ip地址的主機名booleanisMulticastAddress()檢查InetAddress是否是ip多播地址booleanisReachable(inttimeout)測試是否可以達到該地址StringtoString()將此ip地址轉換為String【例10-3】:通過案例來掌握使用InetAddress類遠端主機的ip地址和主機名。功能實現(xiàn):使用InetAddress對象獲取internet網(wǎng)上指定主機和本地主機的有關信息。import.InetAddress;import.UnknownHostException;publicclassDemo10_03{ publicstaticvoidmain(Stringargs[]){ try{ //獲取給定域名的地址 InetAddressinetAddress1=InetAddress.getByName(""); System.out.println(inetAddress1.getHostName());//顯示主機名 System.out.println(inetAddress1.getHostAddress());//顯示IP地址 System.out.println(inetAddress1);//顯示地址的字符串描述 //獲取本機的地址 InetAddressinetAddress2=InetAddress.getLocalHost(); System.out.println(inetAddress2.getHostName()); System.out.println(inetAddress2.getHostAddress()); System.out.println(inetAddress2); //獲取給定IP的主機地址(5) byte[]bs=newbyte[]{(byte)72,(byte)5,(byte)124,(byte)55}; InetAddressinetAddress3=InetAddress.getByAddress(bs); InetAddressinetAddress4=InetAddress.getByAddress("Sun官方網(wǎng)站()",bs); System.out.println(inetAddress3); System.out.println(inetAddress4); }catch(UnknownHostExceptione){ e.printStackTrace(); } }}該程序的運行結果:關于Java
Socket編程的詳細介紹事實上網(wǎng)絡編程簡單的理解就是兩臺計算機相互通訊數(shù)據(jù)而已,對于程序員而言,去掌握一種編程接口并使用一種編程模型相對就會顯得簡單的多了。Java
SDK提供一些相對簡單的Api來完成這些工作。Socket就是其中之一。對于Java而言,這些Api存在與
這個包里面。因此只要導入這個包就可以準備網(wǎng)絡編程了ServerSocket構造方法: 表10.6ServerSocket常用方法:表10.7ServerSocket:構造方法主要功能ServerSocket()創(chuàng)建未綁定的服務器套接字ServerSocket(intport)創(chuàng)建綁定到指定端口的服務器套接字ServerSocket(intport,intbacklog)創(chuàng)建服務器套接字并將其綁定到指定的本地端口號,并指定了積壓ServerSocket(intport,intbacklog,InetAddressbindAddr)創(chuàng)建一個具有指定端口的服務器,偵聽backlog和本地IP地址綁定方法主要功能Socketaccept()偵聽并接受此套接字的連接voidbind(SocketAddressendpoint)將ServerSocket綁定到特定地址(ip地址和端口號)voidbind(SocketAddressendpoint,intbacklog)在有多個網(wǎng)卡(每個網(wǎng)卡都有自己的ip地址)的服務器上,將ServerSocket綁定到特定地址(ip地址和端口號),并設置最長連接隊列voidclose()關閉此套接字InetAddressgetInetAddress()返回此服務器套接字的本地地址IntgetLocalPort()返回此套接字在其上偵聽的端口SocketAddressgetLocalSocketAddress()返回此套接字綁定的端口的地址,如果尚未綁定則返回nullbooleanisBound()返回ServerSocket的綁定狀態(tài)booleanisClosed()返回ServerSocket的關閉狀態(tài)StringtoString()作為String返回此套接字的實現(xiàn)地址和實現(xiàn)端口【例10-4】:通過案例來掌握使用ServerSocket類獲取服務器的狀態(tài)信息。功能測試:測試ServerSocket中部分方法的功能。importjava.io.*;import.ServerSocket;publicclassDemo10_04{ publicstaticvoidmain(Stringargs[]){ ServerSocketserverSocket=null; try{ serverSocket=newServerSocket(2010); System.out.println("服務器端口:"+serverSocket.getLocalPort()); System.out.println("服務器地址:"+serverSocket.getInetAddress()); System.out.println("服務器套接字:"+serverSocket.getLocalSocketAddress()); System.out.println("是否綁定連接:"+serverSocket.isBound()); System.out.println("連接是否關閉:"+serverSocket.isClosed()); System.out.println("服務器套接字詳情:"+serverSocket.toString()); }catch(IOExceptione1){ System.out.println(e1); } }}該程序的運行結果:在Java中Socket可以理解為客戶端或者服務器端的一個特殊的對象,這個對象有兩個關鍵的方法,一個是getInputStream方法,另一個是getOutputStream方法。getInputStream方法可以得到一個輸入流,客戶端的Socket對象上的getInputStream方法得到的輸入流其實就是從服務器端發(fā)回的數(shù)據(jù)流。GetOutputStream方法得到一個輸出流,客戶端Socket對象上的getOutputStream方法返回的輸出流就是將要發(fā)送到服務器端的數(shù)據(jù)流,(其實是一個緩沖區(qū),暫時存儲將要發(fā)送過去的數(shù)據(jù))。Socket構造方法:表10.8ocket常用方法:表10.9Socket類:構造方法主要功能Socket()創(chuàng)建一個未連接的套接字,并使用系統(tǒng)默認類型的SocketImplSocket(InetAddressaddress,intport)創(chuàng)建流套接字并將其連接到指定IP地址的指定端口號方法主要功能InetAddressgetInetAddress()返回套接字連接的地址InetAddressgetLocalAddress()獲取套接字綁定的本地地址intgetLocalPort()返回此套接字綁定到的本地端口SocketAddressgetLocalSocketAddress()返回此套接字綁定的端點的地址,如果尚未綁定則返回nullInputStreamgetInputSteam()返回此套接字的輸入流OutputStreamgetOutputStream()返回此套接字的輸出流intgetPort()返回此套接字連接到的遠程端口booleanisBound()返回套接字的綁定狀態(tài)booleanisClosed()返回套接字的關閉狀態(tài)booleanisConnected()返回套接字的連接狀態(tài)voidconnect(SocketAddressendpoint,inttimeout)將此套接字連接到服務器,并指定一個超時值voidclose()關閉此套接字【例10-5】:通過案例來掌握使用Socket類獲取指定連接的狀態(tài)信息。功能實現(xiàn):測試Socket中部分方法的功能。import.Socket;publicclassDemo10_05{ publicstaticvoidmain(Stringargs[]){ Socketsocket; try{ socket=newSocket("7",4700); System.out.println("是否綁定連接:"+socket.isBound()); System.out.println("本地端口:"+socket.getLocalPort()); System.out.println("連接服務器的端口:"+socket.getPort()); System.out.println("連接服務器的地址:"+socket.getInetAddress()); System.out.println("遠程服務器的套接字:"+socket.getRemoteSocketAddress()); System.out.println("是否處于連接狀態(tài):"+socket.isConnected()); System.out.println("客戶套接詳情:"+socket.toString()); }catch(Exceptione){ System.out.println("服務器端沒有啟動"); } }}該程序的運行結果:打開服務端運行結果:未打開服務端運行結果:【例10-6】:實現(xiàn)簡單的聊天功能//TalkServer.javaimportjava.io.*;import.*;publicclassTalkServer{ publicstaticvoidmain(Stringargs[]){ try{ ServerSocketserver=null; try{ server=newServerSocket(4700); }catch(Exceptione){ System.out.println("cannotlistento:"+e); } Socketsocket=null; try{ socket=server.accept(); }catch(Exceptione){ System.out.println("Error:"+e); } Stringline; BufferedReaderis=newBufferedReader(newInputStreamReader( socket.getInputStream())); PrintWriteros=newPrintWriter(socket.getOutputStream()); BufferedReadersin=newBufferedReader(newInputStreamReader(System.in)); System.out.println("Client:"+is.readLine()); line=sin.readLine(); while(!line.equals("bye")){ os.println(line); os.flush(); System.out.println("Server:"+line); System.out.println("Client:"+is.readLine()); line=sin.readLine(); } is.close(); os.close(); socket.close(); server.close(); }catch(Exceptione){ System.out.println("Error"+e); } }} //TalkClient.javaimportjava.io.*;import.*;publicclassTalkClient{ publicstaticvoidmain(Stringargs[]){ try{ Socketsocket=newSocket("",4700); BufferedReadersin=newBufferedReader(newInputStreamReader(System.in)); PrintWriteros=newPrintWriter(socket.getOutputStream()); BufferedReaderis=newBufferedReader(newInputStreamReader(socket.getInputStream())); Stringreadline; readline=sin.readLine(); while(!readline.equals("bye")){ os.println(readline); os.flush(); System.out.println("Client:"+readline); System.out.println("Server:"+is.readLine()); readline=sin.readLine(); } os.close(); is.close(); socket.close(); }catch(Exceptione){ System.out.println("Error"+e); } }}該程序的運行結果:TalkServer運行結果:TalkClient運行結果:UDP
是UserDatagramProtocol
的簡稱,是一種無連接的協(xié)議,每個數(shù)據(jù)報都是一個獨立的信息,包括完整的源地址或目的地址,它在網(wǎng)絡上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內(nèi)容的正確性都是不能被保證的。DatagramPacket:數(shù)據(jù)報包用來實現(xiàn)無連接包投遞服務。每條報文僅根據(jù)該包中包含的信息從一臺機器路由到另一臺機器。從一臺機器發(fā)送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。不對包投遞做出保證。要發(fā)送和接受數(shù)據(jù)報,需要用DatagramPacket類將數(shù)據(jù)打包,即用DatagramPacket類創(chuàng)建一個對象,稱為數(shù)據(jù)包?;赨DP協(xié)議的網(wǎng)絡編程DatagramPackeg(bytedata[],intlen,InetAddress,intport);數(shù)組是數(shù)據(jù)包內(nèi)容,len為數(shù)據(jù)包長度,add為數(shù)據(jù)包發(fā)送地址,port為接受主機對應的應用。DatagramPackeg(bytedata[],intoffset,intlen,InetAddress,intport);數(shù)據(jù)包內(nèi)容為數(shù)組從offset開始長度為len為數(shù)據(jù),add為數(shù)據(jù)包發(fā)送地址,port為接受主機對應的應用。舉例:Byte[]data=”數(shù)據(jù)包內(nèi)容”.getByte();InetAdressadd=InetAdress.getName(“”);DatagramPacketdatagram=newDatagramPacket(data,data.length,add,1234);對應的構造方法如下:
發(fā)送數(shù)據(jù)和接受數(shù)據(jù):發(fā)送數(shù)據(jù):數(shù)據(jù)包準備好了,就使用DatagramSocket對象的send()方法可以發(fā)送數(shù)據(jù)。DatagramSocketmail=newDatagramSocket();mail.send(datagram);接受數(shù)據(jù):DatagramSocket對象的receive()方法接收數(shù)據(jù),必須提前確定接收方的地址和端口號和數(shù)據(jù)包地址和端口號吻合。Bytedata[]=newbyte[500];DatagramSocketmail=newDatagramPacketSocket(1234);DatagramPacketdatagram=newDatagramPacket(data,data.length);mail.receive(datagram);【例10-7】:客戶端發(fā)送1,2,3,4,5數(shù)據(jù),服務端接受該數(shù)據(jù)并顯示。//TestDatagramClient.javaimport.*;publicclassTestDatagramClient{ publicstaticvoidmain(String[]args){ bytedata[]={1,2,3,4,5}; try{ InetAddressadd=InetAddress.getByName(""); DatagramPacketdatagram=newDatagramPacket(data,data.length,add,12345); DatagramSocketds; ds=newDatagramSocket(); ds.send(datagram);for(byteb:data) System.out.print(b+""); }catch(Exceptione){ e.printStackTrace(); } }}//TestDatagramServer.javaimport.*; publicclassTestDatagramServer{ publicstaticvoidmain(String[]args){ bytedata[]=newbyte[5]; DatagramSocketds; try{ DatagramPacketdp=newDatagramPacket(data,data.length); ds=newDatagramSocket(12345); ds.receive(dp); for(inti=0;i<data.length;i++){ System.out.print(data[i]+","); } }catch(Exceptione){ e.printStackTrace();}}}該程序的運行結果:TestDatagramServer運行結果:TestDatagramClient運行結果:常用方法:表10.10方法主要功能inetAddressgetAddress()返回某臺機器的ip地址,此數(shù)據(jù)報將要發(fā)往該機器或者是從該機器接收到的byte[]getData()返回數(shù)據(jù)緩沖區(qū)intgetLength()返回將要發(fā)送或接收到的數(shù)據(jù)的長度intgetOffset()返回將要發(fā)送或接收到的數(shù)據(jù)的偏移量intgetPort()返回某臺主機的端口號,此數(shù)據(jù)報將要發(fā)往該主機或者是從該主機接收到的SocketAddressgetSocketAddress()獲取要將此包發(fā)送到的或發(fā)出此數(shù)據(jù)報的遠程主機的SocketAddress(通常為ip地址+端口號voidsetAddress(InetAddressiaddr)設置要將此數(shù)據(jù)報發(fā)往的那臺機器的ip地址voidsetData(byte[]buf)為此包設置數(shù)據(jù)緩沖區(qū)voidsetLength(intlength)為此包設置長度voidsetPort(intiport)設置要將此數(shù)據(jù)報發(fā)往的遠程主機上的端口號voidsetSocketAddress(SocketAddressaddress)設置要將此數(shù)據(jù)報發(fā)往的遠程主機的SocketAddress(通常為ip地址+端口號)DatagramSocket:6、DatagramSocket:此類表示用來發(fā)送和接收數(shù)據(jù)報包的套接字。數(shù)據(jù)報套接字是包投遞服務的發(fā)送或接收點。每個在數(shù)據(jù)報套接字上發(fā)送或接收的包都是單獨編址和路由的。從一臺機器發(fā)送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。構造方法:表10.11常用方法:表10.12構造方法主要功能DatagramSocket()構造數(shù)據(jù)報套接字并將其綁定到本地主機上的任何可用端口DatagramSocket(intport)構造數(shù)據(jù)報套接字并將其綁定到本地主機上的指定端口DatagramSocket(intport,InetAddressladdr)創(chuàng)建一個數(shù)據(jù)報套接字,綁定到指定的本地地址DatagramSocket(SocketAddressbindaddr)創(chuàng)建一個數(shù)據(jù)報套接字,綁定到指定的本地套接字地址方法主要功能voidbind(SocketAddressaddr)將此DatagramSocket綁定到特定的地址和端口voidclose()關閉此數(shù)據(jù)報套接字voidconnect(InetAddressaddress,intport)將此套接字連接到遠程套接字地址(ip地址+端口)voidconnect(SocketAddressaddr)將此套接字連接到遠程套接字地址voiddisconnect()斷開套接字的連接InetAddressgetInetAddress()返回此套接字連接的地址InetAddressgetLocalAddress()獲取套接字綁定的本地地址intgetLocalPort()返回此套接字綁定的本地主機上的端口號SocketAddressgetLocalSocketAddress()返回此套接字綁定的端點的地址,如果尚未綁定則返回nullSocketAddressgetRemoteSocketAdddress()返回此套接字連接的端點的地址,如果未連接則返回nullvoidreceive(DatagramPacketp)從此套接字接收數(shù)據(jù)包voidsend(DatagramPacketp)從此套接字發(fā)送數(shù)據(jù)包【例10-8】:通過案例來掌握UDP協(xié)議的網(wǎng)絡編程//TestUDPClient.javaimport.*;importjava.io.*;publicclassTestUDPClient{ publicstaticvoidmain(Stringargs[])throwsException{ longn=10000L; ByteArrayOutputStreambaos=newByteArrayOutputStream(); DataOutputStreamdos=newDataOutputStream(baos); dos.writeLong(n); byte[]buf=baos.toByteArray(); System.out.println(buf.length); DatagramPacketdp=newDatagramPacket(buf,buf.length,newInetSocketAddress("",5678)); DatagramSocketds=newDatagramSocket(9999); ds.send(dp); ds.close();}}//TestUDPServer.javaimport.*;importjava.io.*;publicclassTestUDPServer{ publicstaticvoidmain(Stringargs[])throwsException{ bytebuf[]=newbyte[1024]; DatagramPacketdp=newDatagramPacket(buf,buf.length); DatagramSocketds=newDatagramSocket(5678); while(true){ ds.receive(dp); ByteArrayInputStreambais=newByteArrayInputStream(buf); DataInputStreamdis=newDataInputStream(bais); System.out.println(dis.readLong());}}}該程序的運行結果:TestUDPServer運行結果:TestUDPClient運行結果:任務進階服務器端程序創(chuàng)建套接字,并等待客戶端請求??蛻舳藙?chuàng)建套接字,每秒發(fā)過去一個數(shù)字,并等待接收服務器返回的結果,服務器端接收請求,并將處理結果送回去,再次等待其他請求,而客戶端接收到數(shù)據(jù)后繼續(xù)發(fā)送請求(共10次)??蛻舳薸mportjava.io.*;import.Socket;publicclassclient{ publicstaticvoidmain(String[]args){ Strings=null; Socketc; DataInputStreamin=null; DataOutputStreamout=null; inti=1; try{ c=newSocket("localhost",2345); in=newDataInputStream(c.getInputStream()); out=newDataOutputStream(c.getOutputStream()); out.writeInt(i); while(i<=10){ s=in.readUTF();
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 酒店前臺接待員工作總結
- 高校教研工作的持續(xù)改進與創(chuàng)新
- 金融科技行業(yè)技術職位總結
- 互娛行業(yè)花絮分享培訓心得
- 有效規(guī)劃財務部年終工作總結
- 人機界面設計師界面設計交互設計
- 高危行業(yè)安全監(jiān)管工作方案計劃
- 設備維修維護合同范本完整版
- 司法行業(yè)審判培訓
- 服裝店前臺接待工作總結
- 《理想信念教育》課件
- 2023年高級EHS工程師年度總結及下年工作展望
- 《城市規(guī)劃原理試題》(附答案)
- 110kV升壓站構支架組立施工方案
- 鋼構件應力超聲檢測技術規(guī)程
- -《多軸數(shù)控加工及工藝》(第二版)教案
- 體 育 課 教 學 評 價 量 表
- 23秋國家開放大學《漢語國際教育概論》階段測驗1-2+教學活動1參考答案
- 新員工信息安全課件培訓
- 小學英語-Unit3What would you likePartB Let's talk教學設計學情分析教材分析課后反思
- OA系統(tǒng)功能說明書
評論
0/150
提交評論