国产乱人视频免费观看网站,九九精品视频在线观看,九九久re8在线精品视频,日韩久久精品五月综合

<menu id="zjelp"></menu>

    <th id="zjelp"><tbody id="zjelp"><form id="zjelp"></form></tbody></th>
    <small id="zjelp"><menuitem id="zjelp"></menuitem></small>
  • <small id="zjelp"></small>

    <address id="zjelp"></address>
    <address id="zjelp"></address>
    list18

    list18

    ID:81525079

    大?。?58.50 KB

    頁(yè)數(shù):32頁(yè)

    時(shí)間:2023-09-05

    上傳者:U-24289
    list18_第1頁(yè)
    list18_第2頁(yè)
    list18_第3頁(yè)
    list18_第4頁(yè)
    list18_第5頁(yè)
    list18_第6頁(yè)
    list18_第7頁(yè)
    list18_第8頁(yè)
    list18_第9頁(yè)
    list18_第10頁(yè)
    資源描述:

    《list18》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在學(xué)術(shù)論文-天天文庫(kù)。

    ----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方第18章網(wǎng)絡(luò)本章討論支持網(wǎng)絡(luò)應(yīng)用的java.net包。它的創(chuàng)建者稱Java為“為網(wǎng)絡(luò)編程”。盡管它只占Java的一小部分,與C++或FORTRAN相比,這種編程語(yǔ)言更有利于編寫網(wǎng)絡(luò)程序。使Java成為好的網(wǎng)絡(luò)語(yǔ)言的正是java.net包定義的類。這些類包裝了由加州大學(xué)的伯克利分校的BSD引入的“套接字(socket)”范型。如果不簡(jiǎn)單介紹UNIX和BSD套接字的歷史對(duì)Internet網(wǎng)絡(luò)庫(kù)的討論就是不完整的。18.1網(wǎng)絡(luò)基礎(chǔ)1969年,KenThompson和DennisRitchie在MurrayHill,NewJersey的貝爾電話實(shí)驗(yàn)室開(kāi)發(fā)了與C語(yǔ)言一致的UNIX。很多年來(lái),UNIX的發(fā)展停留在貝爾實(shí)驗(yàn)室和一些大學(xué)及研究機(jī)構(gòu),用特意設(shè)計(jì)的DECPDP機(jī)器運(yùn)行。到了1978年,BillJoy在CalBerkeley領(lǐng)導(dǎo)了一個(gè)項(xiàng)目,給UNIX增添新的特性,例如虛擬內(nèi)存和全屏顯示功能。到了1984年早期,當(dāng)Bill正準(zhǔn)備建立SunMicrosystems,它發(fā)明了4.2BSD,即眾所周知的BerkeleyUNIX。4.2BSD帶有快速文件系統(tǒng)、可靠信號(hào)處理、進(jìn)程間通信以及最重要的網(wǎng)絡(luò)功能。最先在4.2中發(fā)現(xiàn)的網(wǎng)絡(luò)支持后來(lái)成為了實(shí)際的Internet標(biāo)準(zhǔn)。Berkeley的TCP/IP實(shí)現(xiàn)保留了在Internet內(nèi)通信的最初的標(biāo)準(zhǔn)。進(jìn)程間和網(wǎng)絡(luò)通信的套接字范型被Berkeley以外的系統(tǒng)廣泛采用。甚至Window和Macintosh在20世紀(jì)80年代晚期也開(kāi)始和“Berkeley套接字”談話。18.1.1套接字概述網(wǎng)絡(luò)套接字(networksocket)有一點(diǎn)像電源插座。網(wǎng)絡(luò)周圍的各式插頭有一個(gè)標(biāo)準(zhǔn)方法傳輸它們的有效負(fù)載。理解標(biāo)準(zhǔn)協(xié)議的任何東西都能夠插入套接字并進(jìn)行通信。對(duì)于電源插座,不論你插入一個(gè)電燈或是烤箱,只要它們使用60HZ,115伏電壓,設(shè)備將會(huì)工作。思考一下你的用電賬單是怎樣生成的。在你的房子和電網(wǎng)支架間可能有1米的距離,經(jīng)過(guò)這一米的每千瓦電都將列入賬單。賬單到達(dá)你的“地址”。所以,雖然電流在電源插座周圍是自由流動(dòng)的,你房子的所有插頭都是有特定的地址的。除了我們談?wù)摰氖荰CP/IP包和IP地址而不是電器和街道地址外,同樣的思想被應(yīng)用到網(wǎng)絡(luò)套接字。InternetProtocol(IP)是一種低級(jí)路由協(xié)議。該協(xié)議將數(shù)據(jù)分解成小包然后通過(guò)網(wǎng)絡(luò)傳到一個(gè)地址,它并不確保傳輸?shù)男畔欢ǖ竭_(dá)目的。傳輸控制協(xié)議(TCP)是一種較高級(jí)的協(xié)議,它把這些信息包有力的捆綁在一起,在必要的時(shí)候,排序和重傳這些信息包以獲得可靠的數(shù)據(jù)傳輸。第三種協(xié)議,用戶數(shù)據(jù)報(bào)協(xié)議(UDP)幾乎與TCP協(xié)議相當(dāng),并能夠直接用來(lái)支持快速的、無(wú)連接的、不可靠的信息包傳輸。

    1----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方18.1.2客戶/服務(wù)器模式你經(jīng)常在與網(wǎng)絡(luò)有關(guān)的話題中聽(tīng)說(shuō)客戶/服務(wù)器(client/server)這個(gè)術(shù)語(yǔ)。在一些產(chǎn)品說(shuō)明中,這個(gè)概念似乎非常復(fù)雜,其實(shí)它的含義很簡(jiǎn)單。服務(wù)器(server)就是能夠提供共享資源的任何東西?,F(xiàn)在有計(jì)算服務(wù)器,提供計(jì)算功能;打印服務(wù)器,管理多個(gè)打印機(jī);磁盤服務(wù)器,提供聯(lián)網(wǎng)的磁盤空間;以及Web服務(wù)器,用來(lái)存儲(chǔ)網(wǎng)頁(yè)。客戶(client)是簡(jiǎn)單的任何有權(quán)訪問(wèn)特定服務(wù)器的實(shí)體??蛻艉头?wù)器之間的連接就像電燈和電源插頭的連接。房間的電源插座是服務(wù)器,電燈是客戶。服務(wù)器是永久的資源,在訪問(wèn)過(guò)服務(wù)器之后,客戶可以自由的“拔去插頭”。在Berkeley套接字中,套接字的概念允許單個(gè)計(jì)算機(jī)同時(shí)服務(wù)于很多不同的客戶,并能夠提供不同類型信息的服務(wù)。該種技術(shù)由引入的端口(port)處理,此端口是一個(gè)特定機(jī)器上的被編號(hào)的套接字。服務(wù)器進(jìn)程是在“監(jiān)聽(tīng)”端口直到客戶連到它。盡管每個(gè)客戶部分是獨(dú)特的,一個(gè)服務(wù)器允許在同樣端口接受多個(gè)客戶。為管理多個(gè)客戶連接,服務(wù)器進(jìn)程必須是多線程的,或者有同步輸入/輸出處理多路復(fù)用技術(shù)的其他方法。18.1.3保留套接字一旦連接成功,一個(gè)高級(jí)的協(xié)議跟著生效,該協(xié)議與所使用的端口有關(guān)。TCP/IP為特定協(xié)議保留了低端的1024個(gè)端口。如果你在網(wǎng)絡(luò)上沖浪有一些時(shí)間了,那么這中間的很多你已經(jīng)很熟悉了。端口21是為FTP的,23是Telnet,25是為e-mail,79是為finger的,80是HTTP,119是為網(wǎng)絡(luò)新聞的——等等。下面該輪到講述每個(gè)協(xié)議決定客戶如何與端口交互了。舉例來(lái)說(shuō),HTTP是網(wǎng)絡(luò)瀏覽器及服務(wù)器用來(lái)傳輸超文本網(wǎng)頁(yè)和圖像的協(xié)議。它是基本網(wǎng)頁(yè)瀏覽服務(wù)器的一個(gè)非常簡(jiǎn)單的協(xié)議。下面是它的工作原理。當(dāng)一個(gè)客戶向一個(gè)HTTP服務(wù)器請(qǐng)求一個(gè)文件時(shí),即一個(gè)點(diǎn)擊動(dòng)作,它僅僅以一種特定格式向預(yù)先指定的端口打印文件名然后讀回文件的內(nèi)容。服務(wù)器同樣對(duì)狀態(tài)代碼編號(hào)反應(yīng),告訴客戶請(qǐng)求是否被執(zhí)行以及原因。下面是一個(gè)例子??蛻粽?qǐng)求單個(gè)文件/index.html,服務(wù)器回應(yīng)它已成功找到該文件并且把文件傳輸?shù)娇蛻簦悍?wù)器客戶監(jiān)聽(tīng)80端口與端口80連接接受連接寫“GET/index.htmlHTTP/1.0

    2

    3”讀取數(shù)據(jù)直到遇到第二個(gè)換行符(

    4)知道GET是一個(gè)命令,HTTP/1.0是有效的協(xié)議讀取名為/index.html的本地文件寫“HTTP/1.0200OK

    5

    6”“200”意味著“文件來(lái)了”向套接字復(fù)制文件內(nèi)容讀取文件內(nèi)容并顯示掛起掛起

    7----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方很明顯,HTTP協(xié)議比該例顯示的要復(fù)雜的多,但這是一個(gè)實(shí)際的和附近Web服務(wù)器的傳輸。18.1.4代理服務(wù)器一個(gè)代理服務(wù)器(proxyserver)以客戶端協(xié)議與其他服務(wù)器通信。這在客戶與服務(wù)器連接受到某些限制的情況下經(jīng)常是必需的。這樣,客戶可以連接代理服務(wù)器,代理服務(wù)器沒(méi)有這些限制并且代理服務(wù)器也會(huì)依次和客戶通信。代理服務(wù)器具有過(guò)濾某些請(qǐng)求或緩存一些這樣的請(qǐng)求的結(jié)果以備后用的額外功能。一個(gè)緩沖代理HTTP服務(wù)器可用來(lái)減小局域網(wǎng)連向Internet的帶寬要求。若一個(gè)流行網(wǎng)站的網(wǎng)址被成百上千個(gè)用戶點(diǎn)擊,代理服務(wù)器可以一次獲得該網(wǎng)絡(luò)服務(wù)器的流行網(wǎng)頁(yè),節(jié)省昂貴的Internet網(wǎng)絡(luò)傳輸,同時(shí)為用戶快速提供對(duì)這些網(wǎng)頁(yè)的訪問(wèn)。本章的后面部分,我們將實(shí)際建立一個(gè)完整的緩沖代理HTTP服務(wù)器。這個(gè)程序有趣的是它既是客戶又是服務(wù)器。為服務(wù)于某些網(wǎng)頁(yè),它必須像客戶那樣向其他服務(wù)器獲取被請(qǐng)求內(nèi)容的一個(gè)拷貝。18.1.5Internet編址Internet上的每一臺(tái)計(jì)算機(jī)都有一個(gè)地址。Internet地址是網(wǎng)絡(luò)上標(biāo)識(shí)每臺(tái)計(jì)算機(jī)的惟一定義的數(shù)。IP地址有32位,我們通常把它們分成4個(gè)從0到255的,有點(diǎn)號(hào)(.)隔開(kāi)的序列。這使它們易于記憶,因?yàn)樗鼈儾皇请S機(jī)指派的——它們是按層次結(jié)構(gòu)指派的。最開(kāi)始的字節(jié)定義了網(wǎng)絡(luò)屬于A、B、C、D或E哪個(gè)等級(jí)。多數(shù)Internet用戶使用C級(jí),因?yàn)橛卸嘤趦砂偃f(wàn)的網(wǎng)絡(luò)是在C類。C類網(wǎng)的開(kāi)始字節(jié)從192到224,最后字節(jié)實(shí)際上標(biāo)識(shí)了256之中可以上單個(gè)C類網(wǎng)的獨(dú)立計(jì)算機(jī)。這種安排允許在C類網(wǎng)中可以有5億的設(shè)備。域名服務(wù)(DNS)如果每臺(tái)機(jī)器必須用數(shù)字作為它們的地址,Internet不是一個(gè)漫游的友好場(chǎng)所。例如,設(shè)想在廣告的底部看見(jiàn)“http://192.9.9.1/”,這一定使人頭昏腦脹。感謝上帝,存在一個(gè)與所有這些數(shù)字相伴的一個(gè)平行層次的名稱的交換所,叫做域名服務(wù)(DNS)。就像IP地址中從左到右描繪網(wǎng)絡(luò)層次的四個(gè)數(shù)字一樣,Internet地址的名稱,域名,在名稱空間從右到左描述了機(jī)器的地址。例如,www.osborne.com是在COM域(為美國(guó)商業(yè)企業(yè)保留)中的,叫做osborne(公司名稱)的,www是Osborne的Web服務(wù)器的特定計(jì)算機(jī)的名稱。www在意義上相應(yīng)于IP地址的最右邊的數(shù)字。18.2JAVA和網(wǎng)絡(luò)現(xiàn)在準(zhǔn)備工作已經(jīng)完成,讓我們看看Java怎樣和所有的這些網(wǎng)絡(luò)概念相聯(lián)系。Java

    8----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方通過(guò)擴(kuò)展第17章介紹的已有的流式輸入/輸出接口和增加在網(wǎng)絡(luò)上建立輸入/輸出對(duì)象特性這兩個(gè)方法支持TCP/IP。Java支持TCP和UDP協(xié)議族。TCP用于網(wǎng)絡(luò)的可靠的流式輸入/輸出。UDP支持更簡(jiǎn)單的、快速的、點(diǎn)對(duì)點(diǎn)的數(shù)據(jù)報(bào)模式。18.2.1網(wǎng)絡(luò)類和接口java.net包所包含的類如下:Authenticator(Java2)JarURLConnection(Java2)SocketPermissionContentHandlerMulticastSocketURLDatagramPacketNetPermissionURLClassLoader(Java2)DatagramSocketPasswordAuthentication(Java2)URLConnectionDatagramSocketImplServerSocketURLDecoder(Java2)HttpURLConnectionSocketURLEncoderInetAddressSocketImplURLStreamHandlerjava.net包的接口如下:ContentHandlerFactorySocketImplFactoryURLStreamHandlerFactoryFileNameMapSocketOptionsDatagramSocketImplFactory(Java2,v1.3中添加的)下面我們將討論主要的網(wǎng)絡(luò)類并且一些應(yīng)用例子。18.3InetAddress類無(wú)論你是在打電話、發(fā)送郵件或建立與Internet的連接,地址是基礎(chǔ)。InetAddress類用來(lái)封裝我們前面討論的數(shù)字式的IP地址和該地址的域名。你通過(guò)一個(gè)IP主機(jī)名與這個(gè)類發(fā)生作用,IP主機(jī)名比它的IP地址用起來(lái)更簡(jiǎn)便更容易理解。InetAddress類內(nèi)部隱藏了地址數(shù)字。18.3.1工廠方法InetAddress類沒(méi)有明顯的構(gòu)造函數(shù)。為生成一個(gè)InetAddress對(duì)象,必須運(yùn)用一個(gè)可用的工廠方法。工廠方法(factorymethod)僅是一個(gè)類中靜態(tài)方法返回一個(gè)該類實(shí)例的約定。這是在一個(gè)帶有各種參數(shù)列表的重載構(gòu)造函數(shù)完成的,當(dāng)持有惟一方法名時(shí)可使結(jié)果更清晰。對(duì)于InetAddress,三個(gè)方法getLocalHost(?)、getByName(?)以及getAllByName(?)可以用來(lái)創(chuàng)建InetAddress的實(shí)例。三個(gè)方法顯示如下:staticInetAddressgetLocalHost(?)??throwsUnknownHostExceptionstaticInetAddressgetByName(StringhostName)??throwsUnknownHostExceptionstaticInetAddress[]getAllByName(StringhostName)??throwsUnknownHostExceptiongetLocalHost(?)僅返回象征本地主機(jī)的InetAddress對(duì)象。getByName(?)

    9----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方方法返回一個(gè)傳給它的主機(jī)名的InetAddress。如果這些方法不能解決主機(jī)名,它們引發(fā)一個(gè)UnknownHostException異常。在Internet上,用一個(gè)名稱來(lái)代表多個(gè)機(jī)器是很常有的事。Web服務(wù)器中,也有方法提供一定程度的縮放。getAllByName(?)工廠方法返回代表由一個(gè)特殊名稱分解的所有地址的InetAddresses類數(shù)組。在不能把名稱分解成至少一個(gè)地址時(shí),它將引發(fā)一個(gè)UnknownHostException異常。下面的例子打印了本地機(jī)的地址和名稱以及兩個(gè)著名的Internet網(wǎng)址://DemonstrateInetAddress.importjava.net.*;classInetAddressTest{publicstaticvoidmain(Stringargs[])throwsUnknownHostException{InetAddressAddress=InetAddress.getLocalHost();System.out.println(Address);Address=InetAddress.getByName("osborne.com");System.out.println(Address);InetAddressSW[]=InetAddress.getAllByName("www.nba.com");for(inti=0;i

    10----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方地址在分層的緩存服務(wù)器系列中被找到。這意味著你的本地機(jī)可能像知道它自己和附近的服務(wù)器一樣知道一個(gè)名稱-IP地址的自動(dòng)映射。對(duì)于其他名稱,它可能向一個(gè)本地DNS服務(wù)器詢問(wèn)IP地址信息。如果那個(gè)服務(wù)器不含一個(gè)指定的地址,它可以到一個(gè)遠(yuǎn)程的站點(diǎn)去詢問(wèn)。這可以一路通到名為InterNIC(internic.net)的根服務(wù)器。該過(guò)程可能需要比較長(zhǎng)的時(shí)間,所以結(jié)構(gòu)化你的代碼以使你在本地存儲(chǔ)IP地址信息而不是重復(fù)向上查找信息是一個(gè)明智之舉。

    11----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方18.4TCP/IP客戶套接字TCP/IP套接字用于在主機(jī)和Internet之間建立可靠的、雙向的、持續(xù)的、點(diǎn)對(duì)點(diǎn)的流式連接。一個(gè)套接字可以用來(lái)建立Java的輸入/輸出系統(tǒng)到其他的駐留在本地機(jī)或Internet上的任何機(jī)器的程序的連接。注意:小應(yīng)用程序只建立回到下載它的主機(jī)的套接字連接。存在這個(gè)限制的原因是:穿過(guò)防火墻的小應(yīng)用程序有權(quán)使用任何機(jī)器是很危險(xiǎn)的事情。Java中有兩類TCP套接字。一種是服務(wù)器端的,另一種是客戶端的。ServerSocket類設(shè)計(jì)成在等待客戶建立連接之前不做任何事的“監(jiān)聽(tīng)器”。Socket類為建立連向服務(wù)器套接字以及啟動(dòng)協(xié)議交換而設(shè)計(jì)。一個(gè)Socket對(duì)象的創(chuàng)建隱式建立了一個(gè)客戶和服務(wù)器的連接。沒(méi)有顯式的說(shuō)明建立連接細(xì)節(jié)的方法或構(gòu)造函數(shù)。下面是用來(lái)生成客戶套接字的兩個(gè)構(gòu)造函數(shù):Socket(StringhostName,intport)創(chuàng)建一個(gè)本地主機(jī)與給定名稱的主機(jī)和端口的套接字連接,可以引發(fā)一個(gè)UnknownHostException異?;騃OException異常。Socket(InetAddressipAddress,intport)用一個(gè)預(yù)先存在的InetAddress對(duì)象和端口創(chuàng)建一個(gè)套接字,可以引發(fā)IOException異常。使用下面的方法,可以在任何時(shí)候檢查套接字的地址和與之有關(guān)的端口信息:InetAddressgetInetAddress(?)返回和Socket對(duì)象相關(guān)的InetAddress。IntgetPort(?)返回與該Socket對(duì)象連接的遠(yuǎn)程端口。IntgetLocalPort(?)返回與該Socket連接的本地端口。一旦Socket對(duì)象被創(chuàng)建,同樣可以檢查它獲得訪問(wèn)與之相連的輸入和輸出流的權(quán)力。如果套接字因?yàn)榫W(wǎng)絡(luò)的連接中斷而失效,這些方法都能夠引發(fā)一個(gè)IOException異常。InputStreamgetInputStream(?)返回與調(diào)用套接字有關(guān)的InputStream類。OutputStreamgetOutputStream(?)返回與調(diào)用套接字有關(guān)的OutputStream類。voidclose(?)關(guān)閉InputStream和OutputStream。18.4.1Whois下面的例子打開(kāi)了一個(gè)InterNIC服務(wù)器上“whois”端口的連接,傳輸命令行語(yǔ)句到套接字,然后打印返回的數(shù)據(jù)。InterNIC將努力尋找作為已注冊(cè)的Internet域名的參數(shù),然后傳輸回IP地址和該地點(diǎn)的聯(lián)系信息。//DemonstrateSockets.importjava.net.*;importjava.io.*;

    12----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方classWhois{publicstaticvoidmain(Stringargs[])throwsException{intc;Sockets=newSocket("internic.net",43);InputStreamin=s.getInputStream();OutputStreamout=s.getOutputStream();Stringstr=(args.length==0?"osborne.com":args[0])+"

    13";bytebuf[]=str.getBytes();out.write(buf);while((c=in.read())!=-1){System.out.print((char)c);}s.close();}}例如,如果你在命令行鍵入osborne.com,你將會(huì)獲得下面相似的結(jié)果:WhoisServerVersion1.3Domainnamesinthe.com,.net,and.orgdomainscannowberegisteredwithmanydifferentcompetingregistrars.Gotohttp://www.internic.netfordetailedinformation.DomainName:OSBORNE.COMRegistrar:NETWORKSOLUTIONS,INC.WhoisServer:whois.networksolutions.comReferralURL:www.networksolutions.comNameServer:NS1.EPPG.COMNameServer:NS2.EPPG.COMUpdatedDate:07-apr-2000>>>Lastupdateofwhoisdatabase:Fri,6Oct200010:03:36EDT<<

    14----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方上獲取信息提供了一個(gè)簡(jiǎn)單的、簡(jiǎn)潔的用戶編程接口(API)。18.5.1格式化(Format)http://www.osborne.com/和http://www.osborne.com:80/index.htm是URL的兩個(gè)例子。一個(gè)URL規(guī)范以四個(gè)元素為基礎(chǔ)。第一個(gè)是所用到的協(xié)議,用冒號(hào)(:)來(lái)將它與定位符的其他部分相隔離。盡管現(xiàn)在所有的事情都通過(guò)HTTP(實(shí)際上,如果你在URL規(guī)范中不用“http://”,大多數(shù)瀏覽器都能正確執(zhí)行)完成,但它不是惟一的協(xié)議,常見(jiàn)的協(xié)議有http、ftp、gopher和文件。第二個(gè)元素是主機(jī)名或所用主機(jī)的IP地址,這由左邊的雙斜線(//)和右邊的單斜線(/)或可選冒號(hào)(:)限制。第三個(gè)成分,端口號(hào),是可選的參數(shù),由主機(jī)名左邊的冒號(hào)(:)和右邊的斜線(/)限制(它的默認(rèn)端口為80,它是預(yù)定義的HTTP端口;所以“:80”是多余的)。第四部分是實(shí)際的文件路徑。多數(shù)HTTP服務(wù)器將給URL附加一個(gè)與目錄資源相關(guān)的index.html或index.htm文件。所以,http://www.osborne.com/與http://www.osborne.com/index.htm是相同的。Java的URL類有多個(gè)構(gòu)造函數(shù),每個(gè)都能引發(fā)一個(gè)MalformedURLException異常。一個(gè)常見(jiàn)形式是用與你在瀏覽器中看到的相同的字符串指定URL:URL(StringurlSpecifier)下面的兩個(gè)構(gòu)造函數(shù)形式允許你把URL分裂成它的組成部分:URL(StringprotocolName,StringhostName,intport,Stringpath)URL(StringprotocolName,StringhostName,Stringpath)另一個(gè)經(jīng)常用到的構(gòu)造函數(shù)允許你用一個(gè)已經(jīng)存在的URL作為引用上下文,然后從該上下文中創(chuàng)建一個(gè)新的URL。盡管這聽(tīng)起來(lái)有些別扭,它實(shí)際上是很簡(jiǎn)單而有用的。URL(URLurlObj,StringurlSpecifier)下面的例子中,我們?yōu)镺sborne的下載頁(yè)面創(chuàng)建一個(gè)URL,然后檢查它的屬性://DemonstrateURL.importjava.net.*;classURLDemo{publicstaticvoidmain(Stringargs[])throwsMalformedURLException{URLhp=newURL("http://www.osborne.com/download");System.out.println("Protocol:"+hp.getProtocol());System.out.println("Port:"+hp.getPort());System.out.println("Host:"+hp.getHost());System.out.println("File:"+hp.getFile());System.out.println("Ext:"+hp.toExternalForm());}}運(yùn)行該程序,你將獲得下面輸出:Protocol:httpPort:

    15----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方-1Host:www.osborne.comFile:/downloadExt:http://www.osborne.com/download注意端口是-1,這意味著該端口沒(méi)有被明確設(shè)置。現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)URL對(duì)象,我們希望找回與之相連的數(shù)據(jù)。為獲得URL的實(shí)際比特或內(nèi)容信息,用它的openConnection(?)方法從它創(chuàng)建一個(gè)URLConnection對(duì)象,如下:url.openConnection()openConnection(?)有下面的常用形式:URLConnectionopenConnection(?)與調(diào)用URL對(duì)象相關(guān),它返回一個(gè)URLConnection對(duì)象。它可能引發(fā)IOException異常。18.6URLConnection類URLConnection是訪問(wèn)遠(yuǎn)程資源屬性的一般用途的類。如果你建立了與遠(yuǎn)程服務(wù)器之間的連接,你可以在傳輸它到本地之前用URLConnection來(lái)檢察遠(yuǎn)程對(duì)象的屬性。這些屬性由HTTP協(xié)議規(guī)范定義并且僅對(duì)用HTTP協(xié)議的URL對(duì)象有意義。我們這里將驗(yàn)證URLConnection最有用的原理。下面的例子中我們用一個(gè)URL對(duì)象的openConnection(?)方法創(chuàng)建了一個(gè)URLConnection類,然后用它來(lái)檢查文件的屬性和內(nèi)容://DemonstrateURLConnection.importjava.net.*;importjava.io.*;importjava.util.Date;classUCDemo{publicstaticvoidmain(Stringargs[])throwsException{intc;URLhp=newURL("http://www.osborne.com");URLConnectionhpCon=hp.openConnection();System.out.println("Date:"+newDate(hpCon.getDate()));System.out.println("Content-Type:"+hpCon.getContentType());System.out.println("Expires:"+hpCon.getExpiration());System.out.println("Last-Modified:"+newDate(hpCon.getLastModified()));intlen=hpCon.getContentLength();System.out.println("Content-Length:"+len);if(len>0){System.out.println("===Content===");InputStreaminput=hpCon.getInputStream();inti=len;

    16----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方while(((c=input.read())!=-1)&&(--i>0)){System.out.print((char)c);}input.close();}else{System.out.println("NoContentAvailable");}}}該程序建立了一個(gè)經(jīng)過(guò)端口80通向www.osborne.com的HTTP連接。然后列出了標(biāo)頭值并檢索內(nèi)容。下面是輸出的前幾行:Date:FriOct0614:17:10CDT2000Content-Type:text/htmlExpires:0Last-Modified:TueOct2601:36:57CDT1999Content-Length:529===Content===Osborne/McGraw-Hill:RequiredReadingfortheInformationAgeURL和URLConnection類對(duì)于希望建立與HTTP服務(wù)器的連接來(lái)獲取信息的簡(jiǎn)單程序來(lái)說(shuō)是非常好的。對(duì)于更復(fù)雜的應(yīng)用程序,你會(huì)發(fā)現(xiàn)學(xué)習(xí)HTTP協(xié)議規(guī)范,實(shí)現(xiàn)你自己的包裝程序是比較好的。18.7TCP/IP服務(wù)器套接字如我們?cè)谇懊嫣岬降?,Java具有用來(lái)創(chuàng)建服務(wù)器應(yīng)用程序的不同的套接字類。ServerSocket類用來(lái)創(chuàng)建服務(wù)器,服務(wù)器監(jiān)聽(tīng)本地或遠(yuǎn)程客戶程序通過(guò)公共端口的連接。既然Web驅(qū)動(dòng)著Internet中的大部分活動(dòng),本節(jié)就開(kāi)發(fā)一個(gè)可運(yùn)行的Web服務(wù)器(http)。ServerSocket與通常的Sockets類完全不同。當(dāng)創(chuàng)建一個(gè)ServerSocket類,它在系統(tǒng)注冊(cè)自己對(duì)客戶連接感興趣。ServerSocket的構(gòu)造函數(shù)反映了希望接受連接的端口號(hào)及你希望排隊(duì)等待上述端口的時(shí)間(該項(xiàng)可選)。隊(duì)列長(zhǎng)度告訴系統(tǒng)多少與之連接的客戶在系統(tǒng)拒絕連接之前可以掛起。隊(duì)列的默認(rèn)長(zhǎng)度是50。構(gòu)造函數(shù)在不利情況下可以引發(fā)IOException異常。下面是構(gòu)造函數(shù):ServerSocket(intport)在指定端口創(chuàng)建隊(duì)列長(zhǎng)度為50的服務(wù)器套接字。ServerSocket(intport,intmaxQueue)在指定端口創(chuàng)建一個(gè)最大隊(duì)列長(zhǎng)度為maxQueue的服務(wù)器套接字。

    17----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方ServerSocket(intport,intmaxQueue,????????????????????InetAddresslocalAddress)在指定端口創(chuàng)建一個(gè)最大隊(duì)列長(zhǎng)度為maxQueue的服務(wù)器套接字。在一個(gè)多地址主機(jī)上,localAddress指定該套接字約束的IP地址。ServerSocket有一個(gè)額外的accept()方法,該方法是一個(gè)等待客戶開(kāi)始通信的模塊化調(diào)用,然后以一個(gè)用來(lái)與客戶通信的常規(guī)Socket返回。

    18----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方18.8緩存代理HTTP服務(wù)器本節(jié)的剩余部分,我們講述一個(gè)簡(jiǎn)單的緩存代理HTTP服務(wù)器,名為http,來(lái)演示客戶與服務(wù)器套接字。http只支持GET操作及硬編碼的MIME類型的一小部分(MIME類型是多媒體內(nèi)容的類型描述符)。代理HTTP服務(wù)器是單線程的,該線程中每一個(gè)請(qǐng)求依次被處理,其他請(qǐng)求等待。這是緩存的相當(dāng)天真的策略——它在RAM永久保存所有信息。http作為一個(gè)代理服務(wù)器時(shí),它還拷貝每一個(gè)它獲取的文件到本地緩存中。對(duì)于本地緩存,它沒(méi)有用于刷新和無(wú)用單元回收的策略。除此之外,http代表了客戶和服務(wù)器套接字的一個(gè)多產(chǎn)的例子,它是值得探究和容易擴(kuò)展的。18.8.1源代碼HTTP服務(wù)器是通過(guò)5個(gè)類和一個(gè)接口實(shí)現(xiàn)的。更完善的實(shí)現(xiàn)方案可能在主類httpd外分裂很多的方法,以使組成結(jié)構(gòu)更抽象??紤]本書(shū)的容量,多數(shù)功能是在單個(gè)類中實(shí)現(xiàn)的,小的支持類僅作為數(shù)據(jù)結(jié)構(gòu)。我們仔細(xì)學(xué)習(xí)每一個(gè)類和方法來(lái)了解該服務(wù)器怎樣工作,由支持類開(kāi)始,終止于主程序。MimeHeader.javaMIME是通過(guò)電子郵件系統(tǒng)傳達(dá)多媒體內(nèi)容的一個(gè)Internet標(biāo)準(zhǔn)。該標(biāo)準(zhǔn)是由NatBorenstein在1992年創(chuàng)建的。HTTP協(xié)議運(yùn)用并擴(kuò)展了MIME標(biāo)頭的概念,在HTTP客戶和服務(wù)器之間傳輸常規(guī)的屬性/值對(duì)。構(gòu)造函數(shù)該類是Hashtable的一個(gè)子類,所以它能方便的存儲(chǔ)和檢索與MIME標(biāo)頭有關(guān)的關(guān)鍵字/值對(duì)。它有兩個(gè)構(gòu)造函數(shù)。一個(gè)創(chuàng)建一個(gè)不含關(guān)鍵字的空的MimeHeader。另一個(gè)以一個(gè)格式化的字符串作為MIME標(biāo)頭,然后把它解析為對(duì)象的初始內(nèi)容。參看下面的parse(?)。parse(?)parse(?)方法用來(lái)獲取一個(gè)原始MIME格式的字符串,并使它的關(guān)鍵字/值對(duì)進(jìn)入一個(gè)給定的MimeHeader實(shí)例。它用StringTokenizer把輸入數(shù)據(jù)分解成獨(dú)立的由CRLF(\r

    19)序列標(biāo)記的行。然后用規(guī)范的while...hasMoreTokens(?)...nextToken(?)序列遍歷每一行。對(duì)于MIME標(biāo)頭的每一行,parse(?)通過(guò)冒號(hào)(:)把該行分解成兩個(gè)字符串。兩個(gè)變量key和val由substring(?)方法設(shè)置,用來(lái)提取冒號(hào)前后的字符及后面的空隔。當(dāng)兩個(gè)字符串被提取后,使用put(?)方法存儲(chǔ)Hashtable中的關(guān)鍵字和值之間的關(guān)聯(lián)。toString(?)toString(?)方法(用于String串聯(lián)操作,+)只是parse(?)的反方法。它獲取當(dāng)前存儲(chǔ)在MimeHeader中的關(guān)鍵字/值對(duì),返回一個(gè)MIME格式的字符串描述,然后打印關(guān)鍵字,跟著是冒號(hào)和空隔,然后是值,最后是CRLF。put(?),get(?),ANDfix(?)如果不是特殊的任務(wù),Hashtable中的put(?)和get(?)方法將運(yùn)行良好。MIME規(guī)范定義了幾個(gè)重要的關(guān)鍵字例如Content-Type和Content-Length。一些早期的MIME系統(tǒng)設(shè)備,特別是網(wǎng)絡(luò)瀏覽器,對(duì)這些成員的大小寫是自由的。一些用

    20----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方Content-type,另一些用content-type。為避免災(zāi)禍,我們的HTTP服務(wù)器努力將所有的輸入和輸出的MimeHeader關(guān)鍵字轉(zhuǎn)換成規(guī)范形式Content-Type。因此,我們?cè)谒鼈冞M(jìn)入Hashtable和尋找給定關(guān)鍵字之前用fix()方法重載put(?)和get(?),轉(zhuǎn)變值的大小寫。代碼下面是MimeHeader的源代碼:importjava.util.*;classMimeHeaderextendsHashtable{voidparse(Stringdata){StringTokenizerst=newStringTokenizer(data,"\r

    21");while(st.hasMoreTokens()){Strings=st.nextToken();intcolon=s.indexOf(':');Stringkey=s.substring(0,colon);Stringval=s.substring(colon+2);//skip":"put(key,val);}}MimeHeader(){}MimeHeader(Stringd){parse(d);}publicStringtoString(){Stringret="";Enumeratione=keys();while(e.hasMoreElements()){Stringkey=(String)e.nextElement();Stringval=(String)get(key);ret+=key+":"+val+"\r

    22";}returnret;}//Thissimplefunctionconvertsamimestringfrom//anyvariantofcapitalizationtoacanonicalform.//Forexample:CONTENT-TYPEorcontent-typetoContent-Type,//orContent-lengthorCoNTeNT-LENgthtoContent-Length.privateStringfix(Stringms){charchars[]=ms.toLowerCase().toCharArray();booleanupcaseNext=true;for(inti=0;i

    23----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方upcaseNext=ch=='-';}returnnewString(chars);}publicStringget(Stringkey){return(String)super.get(fix(key));}publicvoidput(Stringkey,Stringval){super.put(fix(key),val);}}HttpResponse.javaHttpResponse類是所有與HTTP服務(wù)器應(yīng)答有關(guān)的事物的包裝程序。它被httpd類的代理部分使用。當(dāng)你向一個(gè)HTTP服務(wù)器發(fā)送一個(gè)請(qǐng)求時(shí),它以一個(gè)存儲(chǔ)在statusCode中的整數(shù)形式的代碼以及一個(gè)存儲(chǔ)在reasonPhrase中的文本應(yīng)答(這些變量名在正式的HTTP規(guī)范中規(guī)定)。這個(gè)單行的響應(yīng)后面跟隨著一個(gè)包含進(jìn)一步應(yīng)答信息的MIME頭。我們用以前解釋過(guò)的MimeHeader對(duì)象來(lái)解析這個(gè)字符串。MimeHeader對(duì)象存儲(chǔ)在HttpResponse類的mh變量中。這些變量不是私有的,所以httpd可以直接使用它們。構(gòu)造函數(shù)如果用一個(gè)字符串參數(shù)創(chuàng)建一個(gè)HttpResponse類對(duì)象,它被用來(lái)作為一個(gè)HTTP服務(wù)器的原始響應(yīng),并傳向下面描述的parse(?)來(lái)初始化對(duì)象。你還可以傳入一個(gè)預(yù)計(jì)算的狀態(tài)碼,原因語(yǔ)句以及MIME標(biāo)頭。parse(?)parse(?)方法獲得從HTTP服務(wù)器上讀取的原始數(shù)據(jù),從第一行解析出statusCode和reasonPhrase,然后在剩下的行外部創(chuàng)建一個(gè)MimeHeader。toString(?)toString(?)方法是parse(?)的逆方法。它獲取HttpResponse對(duì)象的當(dāng)前值并返回一個(gè)字符串,HTTP客戶希望從服務(wù)器讀回該字符串。代碼下面是HttpResponse的源代碼:importjava.io.*;/**HttpResponse*ParseareturnmessageandMIMEheaderfromaserver.*HTTP/1.0302Found=redirection,checkLocationforwhere.*HTTP/1.0200OK=filedatacomesaftermimeheader.*/classHttpResponse{intstatusCode;//Status-CodeinspecStringreasonPhrase;//Reason-PhraseinspecMimeHeadermh;staticStringCRLF="\r

    24";voidparse(Stringrequest){intfsp=request.indexOf('');

    25----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方intnsp=request.indexOf('',fsp+1);inteol=request.indexOf('

    26');Stringprotocol=request.substring(0,fsp);statusCode=Integer.parseInt(request.substring(fsp+1,nsp));reasonPhrase=request.substring(nsp+1,eol);Stringraw_mime_header=request.substring(eol+1);mh=newMimeHeader(raw_mime_header);}HttpResponse(Stringrequest){parse(request);}HttpResponse(intcode,Stringreason,MimeHeaderm){statusCode=code;reasonPhrase=reason;mh=m;}publicStringtoString(){return"HTTP/1.0"+statusCode+""+reasonPhrase+CRLF+mh+CRLF;}}UrlCacheEntry.java為在服務(wù)器上保存文檔的內(nèi)容,必須在用于找回文檔的URL和文檔自身描述之間建立聯(lián)系。一個(gè)文檔由它的MimeHeader和原始數(shù)據(jù)描述。例如一副圖像可以被一個(gè)Content-Type:image/gif樣式的MimeHeader描述,而原始圖像數(shù)據(jù)就是一個(gè)字節(jié)數(shù)組。同樣,一個(gè)網(wǎng)頁(yè)在它的MimeHeader中有Content-Type:text/html關(guān)鍵字/值對(duì),而原始數(shù)據(jù)就是HTML頁(yè)的內(nèi)容。再次申明,實(shí)例變量不是私有的,所以httpd可以自由的訪問(wèn)它們。構(gòu)造函數(shù)UrlCacheEntry對(duì)象的構(gòu)造函數(shù)需要用URL作為關(guān)鍵字以及一個(gè)與之相關(guān)的MimeHeader。如果MimeHeader內(nèi)部有一個(gè)名為Content-Length成員(大多數(shù)情況下如此),數(shù)據(jù)區(qū)域被預(yù)先分配足夠大的空間來(lái)保存它的內(nèi)容。append(?)append(?)方法用來(lái)給UrlCacheEntry對(duì)象增添數(shù)據(jù)的。它不是一個(gè)簡(jiǎn)單的setData(?)方法,原因是數(shù)據(jù)可能流經(jīng)網(wǎng)絡(luò)且需要在一定時(shí)間被存儲(chǔ)成塊。append(?)方法處理三種情形。第一種,數(shù)據(jù)緩沖區(qū)根本沒(méi)有分配。第二種情形,數(shù)據(jù)緩沖區(qū)對(duì)于引入的數(shù)據(jù)來(lái)說(shuō)太小,所以它被重新分配。最后一種情況,引入的數(shù)據(jù)正好可以插入緩沖區(qū)。在任何時(shí)候,length成員變量保存數(shù)據(jù)緩沖區(qū)當(dāng)前的有效大小值。代碼下面是UrlCacheEntry的源代碼:classUrlCacheEntry{Stringurl;MimeHeadermh;bytedata[];intlength=

    27----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方0;publicUrlCacheEntry(Stringu,MimeHeaderm){url=u;mh=m;Stringcl=mh.get("Content-Length");if(cl!=null){data=newbyte[Integer.parseInt(cl)];}}voidappend(byted[],intn){if(data==null){data=newbyte[n];System.arraycopy(d,0,data,0,n);length=n;}elseif(length+n>data.length){byteold[]=data;data=newbyte[old.length+n];System.arraycopy(old,0,data,0,old.length);System.arraycopy(d,0,data,old.length,n);}else{System.arraycopy(d,0,data,length,n);length+=n;}}}LogMessage.javaLogMessage是一個(gè)簡(jiǎn)單的接口,它只定義了一個(gè)方法log(?),該方法只有一個(gè)String型參數(shù)。它用來(lái)抽象從httpd獲得消息的輸出。在應(yīng)用程序條件下,該方法用來(lái)打印標(biāo)準(zhǔn)應(yīng)用程序起始處控制臺(tái)的輸出。在小應(yīng)用程序情況下,數(shù)據(jù)被送到一個(gè)視窗文本緩沖區(qū)。代碼下面是LogMessage的源程序:interfaceLogMessage{publicvoidlog(Stringmsg);}httpd.java這真是一個(gè)具有很多功能的大類。我們將一個(gè)方法一個(gè)方法的講解它。構(gòu)造函數(shù)存在5個(gè)主要的實(shí)例變量:port,docRoot,log,cache和stopFlag,它們都是私有的。其中的三個(gè)可以由httpd的獨(dú)立構(gòu)造函數(shù)設(shè)置,顯示如下:httpd(intp,Stringdr,LogMessagelm)它初始化監(jiān)聽(tīng)端口,初始化檢索文件的目錄以及初始化發(fā)送消息的接口。第四個(gè)實(shí)例變量cache,是在RAM中保存所有文件的Hashtable,它是在對(duì)象創(chuàng)建時(shí)被初始化的。stopFlag控制程序的執(zhí)行。

    28----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方靜態(tài)部分該類中有幾個(gè)重要的靜態(tài)變量。MIME標(biāo)頭中的“Server”域報(bào)告的版本在變量version中被發(fā)現(xiàn)。接著定義了一些常量:HTML文件的MIME類型,mime_text_html;MIME的結(jié)束順序,CRLF;代替原始目錄請(qǐng)求返回的HTML文件名,indexfile以及在輸入/輸出中用到的數(shù)據(jù)緩沖區(qū)的大小,buffer_size。然后mt定義了一系列文件擴(kuò)展名和這些文件相應(yīng)的MIME類型。typesHashtable在下一個(gè)塊中被靜態(tài)初始化,以用來(lái)包含作為可選關(guān)鍵字和值的數(shù)組mt。接著可以用fnameToMimeType(?)方法來(lái)返回傳入的每個(gè)filename的合適的MIME類型。如果filename不含mt表中的任何一個(gè)擴(kuò)展名,該方法返回defaultExt或“text/plain.”。統(tǒng)計(jì)計(jì)算器下面,我們聲明另外5個(gè)實(shí)例變量。它們是沒(méi)有private修飾符,所以一個(gè)外部監(jiān)控器可以檢查這些值并以圖形形式顯示它們(我們將在后面演示)。這些變量表示了我們的Web服務(wù)器所用的統(tǒng)計(jì)資料。點(diǎn)擊數(shù)和提供的字節(jié)的原始數(shù)目被存儲(chǔ)在hits_served和bytes_served中。通常存儲(chǔ)在高速緩存中的文件和字節(jié)數(shù)被存放在files_in_cache和bytes_in_cache中。最后,我們把成功在高速緩存外部提供服務(wù)的點(diǎn)擊數(shù)目存放在hits_to_cache中。toBytes(?)接著,我們有一個(gè)方便的程序,toBytes(?)。該程序把它的字符串轉(zhuǎn)變成一個(gè)字節(jié)數(shù)組。這是十分必要的,因?yàn)镴ava的String對(duì)象是以統(tǒng)一編碼的字符形式存儲(chǔ)的,而Internet協(xié)議中的混合語(yǔ)例如HTTP是老式的8位ASCII碼。makeMimeHeader(?)MakeMimeHeader()方法是另一個(gè)方便的方法,它用來(lái)創(chuàng)建由一些關(guān)鍵字值填充的MimeHeader對(duì)象。該方法返回的MimeHeader在Date成員中含有當(dāng)前時(shí)間和時(shí)期,在Server成員中有服務(wù)器的名稱和版本,Content-Type成員中有type參數(shù),Content-Length成員中有l(wèi)ength參數(shù)。error(?)error(?)方法用來(lái)格式化HTML頁(yè)并返回提出不能完成請(qǐng)求的Web客戶。第一個(gè)參數(shù)code,是返回的出錯(cuò)代碼。一般它在400到499之間。我們的服務(wù)器返回404和405錯(cuò)誤。它用HttpResponse類和適當(dāng)?shù)腗imeHeader來(lái)封裝返回的代碼。該方法返回字符串表示是與HTML頁(yè)有關(guān)的響應(yīng)。該頁(yè)包括易于人讀的錯(cuò)誤代碼信息msg和導(dǎo)致錯(cuò)誤的url請(qǐng)求。getRawRequest(?)GetRawRequest()方法是很簡(jiǎn)單的。它從流讀取數(shù)據(jù)直到它獲得兩個(gè)連續(xù)的換行符。它忽略回車符號(hào)并且只尋找換行符。一旦它已經(jīng)發(fā)現(xiàn)了連續(xù)的兩個(gè)換行符,它使字節(jié)數(shù)組轉(zhuǎn)向一個(gè)String對(duì)象并返回該對(duì)象。如果輸入流在結(jié)束之前沒(méi)有生成兩個(gè)連續(xù)的換行符,它將返回null。這說(shuō)明了HTTP服務(wù)器和客戶的消息是怎樣被格式化的。它們以狀態(tài)的一行開(kāi)始然后立即跟著一個(gè)MIME頭。MIME頭的結(jié)尾被兩個(gè)換行符從剩余的內(nèi)容中分離。logEntry(?)logEntry(?)方法用來(lái)報(bào)告標(biāo)準(zhǔn)格式下的HTTP服務(wù)器的每個(gè)點(diǎn)擊數(shù)。該方法生成的格式也許看起來(lái)有一點(diǎn)奇怪,但是它和HTTP日志文件的當(dāng)前標(biāo)準(zhǔn)相匹配。該方法有若干個(gè)用來(lái)格式化每個(gè)日志項(xiàng)的日期戳的輔助變量和方法。months數(shù)組用來(lái)把月份轉(zhuǎn)換成字符串。當(dāng)host變量接受一個(gè)給定主機(jī)的連接時(shí)它由主HTTP循環(huán)設(shè)置。fmt02d(?)方法把0到9的整數(shù)格式化成兩位的,第一位為零的數(shù),然后結(jié)果字符串通過(guò)LogMessage接口變量log傳輸。

    29----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方writeString(?)另一個(gè)方便的方法writeString(?),用來(lái)隱藏字符到字節(jié)數(shù)組的轉(zhuǎn)變,以使它可以被寫入流。writeUCE(?)writeUCE(?)方法占取一個(gè)OutputStream和一個(gè)UrlCacheEntry。它從高速緩存項(xiàng)提取信息,以便給網(wǎng)絡(luò)客戶傳送消息。消息中包含適當(dāng)?shù)捻憫?yīng)代碼,MIME標(biāo)頭和內(nèi)容。serveFromCache(?)這個(gè)布爾方法試圖在高速緩存中發(fā)現(xiàn)一個(gè)特殊的URL。如果成功,緩存項(xiàng)的內(nèi)容被寫給客戶,hits_to_cache變量遞增,調(diào)用者被返回true。否則,它只返回false。loadFile(?)該方法占用了一個(gè)InputStream、與之相應(yīng)的url以及該URL的MimeHeader。用存儲(chǔ)在MimeHeader的信息創(chuàng)建一個(gè)新的UrlCacheEntry。輸入流在buffer_size字節(jié)塊中被讀取并傳入U(xiǎn)rlCacheEntry。結(jié)果的UrlCacheEntry存儲(chǔ)在高速緩存中。files_in_cache和bytes_in_cache變量更新,UrlCacheEntry返回調(diào)用者。readFile(?)readFile(?)方法就loadFile(?)方法來(lái)說(shuō)看起來(lái)有些多余,實(shí)際不然。該方法嚴(yán)格的從本地文件系統(tǒng)讀取文件。在本地文件系統(tǒng)中,loadFile(?)方法用來(lái)與各種類型的流交流。如果File對(duì)象f存在,將會(huì)為它創(chuàng)建一個(gè)InputStream類。文件的大小是決定了的,MIME類型來(lái)自文件名。當(dāng)loadFile(?)被調(diào)用來(lái)做實(shí)際的讀取和緩存高速工作時(shí),有兩個(gè)變量用來(lái)創(chuàng)建合適的MimeHeader。writeDiskCache(?)writeDiskCache(?)方法占用一個(gè)UrlCacheEntry對(duì)象并且把它持久的寫入本地磁盤。它從URL中建立一個(gè)目錄名,確保用與系統(tǒng)有關(guān)的separatorChar代替斜線(/)字符。然后它調(diào)用mkdirs(?)方法來(lái)保證這個(gè)URL的本地磁盤路徑存在。最后,它打開(kāi)一個(gè)FileOutputStream,向它寫入所有的數(shù)據(jù)然后關(guān)閉它。handleProxy(?)HandleProxy()程序是該服務(wù)器的兩個(gè)主要模式之一?;A(chǔ)思想是:如果你把你的瀏覽器設(shè)置成把該服務(wù)器當(dāng)成代理服務(wù)器,則要傳給它的請(qǐng)求將包括完整的URL,URL中常規(guī)GET方法可刪除“http://”和主機(jī)名部分。我們僅把完整的URL拆碎,尋找“://”序列,其次是斜線(/),然后是使用非標(biāo)準(zhǔn)端口號(hào)的服務(wù)器的另一個(gè)冒號(hào)(:)。一旦我們發(fā)現(xiàn)了這些字符,我們就可以知道已經(jīng)所需要的主機(jī)和端口號(hào)以及我們需要獲取的URL。然后我們可以試圖從RAM高速緩存中轉(zhuǎn)載一個(gè)先前保存過(guò)的文檔版本。如果失敗,我們可以試圖從文件系統(tǒng)裝載它到RAM高速緩存并且再嘗試從RAM高速緩存裝載它。如果此舉失敗,那么事情變得很有趣,因?yàn)槲覀儽仨殢倪h(yuǎn)程站點(diǎn)讀取該文件。為此,我們打開(kāi)一個(gè)遠(yuǎn)程站點(diǎn)和端口的套接字。我們發(fā)送一個(gè)GET請(qǐng)求,要求傳給我們的URL。無(wú)論我們從遠(yuǎn)程站點(diǎn)獲得什么響應(yīng)標(biāo)頭信息,我們把它傳給客戶。如果代碼是200,對(duì)于成功的文件傳輸,我們還把確認(rèn)數(shù)據(jù)流讀到一個(gè)新的UrlCacheEntry類并且把它寫入客戶套接字。然后,我們調(diào)用writeDiskCache(?)來(lái)保存?zhèn)鬏斀Y(jié)果到本地磁盤。我們記錄傳輸日志,關(guān)閉套接字,然后返回。handleGet(?)當(dāng)http后臺(tái)進(jìn)程像一個(gè)普通的Web服務(wù)器一樣工作時(shí),handleGet(?)被調(diào)用。它有一個(gè)服務(wù)于文件的本地磁盤文件根目錄。handleGet(?)的參數(shù)告訴它向何處寫結(jié)果,何處訪問(wèn)URL以及何處請(qǐng)求網(wǎng)絡(luò)瀏覽器的MimeHeader

    30----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方。這個(gè)MIME標(biāo)頭將包括用戶代理字符串和其他有用的屬性。開(kāi)始,我們?cè)噲D在RAM高速緩存外為URL提供服務(wù)。如果此舉失敗,為尋找URL,我們順序訪問(wèn)文件系統(tǒng)。如果文件不存在或不可讀,我們向Web客戶報(bào)告一個(gè)錯(cuò)誤。否則,我們就用readFile(?)方法獲得文件的內(nèi)容并把它們輸入到高速緩存。然后調(diào)用writeUCE(?)方法以用來(lái)傳輸文件內(nèi)容到客戶套接字。doRequest(?)每次連接服務(wù)器時(shí)都會(huì)調(diào)用一次doRequest(?)方法。它解析請(qǐng)求字符串和引入的MIME標(biāo)頭。它在請(qǐng)求字符串中是否存在“://”的基礎(chǔ)上判定是調(diào)用handleProxy(?)還是handleGet(?)方法。如果不用GET,而使用任何其他的方法例如HEAD或POST,該程序向客戶返回一個(gè)405錯(cuò)誤。注意如果stopFlag是true時(shí)HTTP請(qǐng)求被忽略。run(?)run(?)方法在服務(wù)器線程啟動(dòng)時(shí)被調(diào)用。它在指定端口生成一個(gè)新的ServerSocket,在服務(wù)器套接字處進(jìn)入一個(gè)調(diào)用accept(?)的無(wú)限循環(huán),把結(jié)果Socket傳給doRequest(?)作檢查。start(?)ANDstop(?)存在兩個(gè)用來(lái)啟動(dòng)和終止服務(wù)器過(guò)程的方法。這些方法設(shè)置stopFlag的值。main(?)你可以在命令行用main(?)方法來(lái)運(yùn)行應(yīng)用程序。它為服務(wù)器自身設(shè)置LogMessage參數(shù),然后為log(?)提供簡(jiǎn)單的控制臺(tái)輸出執(zhí)行。代碼下面是httpd的源代碼:importjava.net.*;importjava.io.*;importjava.text.*;importjava.util.*;classhttpdimplementsRunnable,LogMessage{privateintport;privateStringdocRoot;privateLogMessagelog;privateHashtablecache=newHashtable();privatebooleanstopFlag;privatestaticStringversion="1.0";privatestaticStringmime_text_html="text/html";privatestaticStringCRLF="\r

    31";privatestaticStringindexfile="index.html";privatestaticintbuffer_size=8192;staticStringmt[]={//mappingfromfileexttoMime-Type"txt","text/plain","html",mime_text_html,"htm","text/html","gif","image/gif","jpg","image/jpg","jpeg","image/jpg","class","application/octet-stream"};staticStringdefaultExt="txt";staticHashtabletypes=newHashtable();static{for(inti=0;i

    32----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方}staticStringfnameToMimeType(Stringfilename){if(filename.endsWith("/"))//specialforindexfiles.returnmime_text_html;intdot=filename.lastIndexOf('.');Stringext=(dot>0)?filename.substring(dot+1):defaultExt;Stringret=(String)types.get(ext);returnret!=null?ret:(String)types.get(defaultExt);}inthits_served=0;intbytes_served=0;intfiles_in_cache=0;intbytes_in_cache=0;inthits_to_cache=0;privatefinalbytetoBytes(Strings)[]{byteb[]=s.getBytes();returnb;}privateMimeHeadermakeMimeHeader(Stringtype,intlength){MimeHeadermh=newMimeHeader();DatecurDate=newDate();TimeZonegmtTz=TimeZone.getTimeZone("GMT");SimpleDateFormatsdf=newSimpleDateFormat("ddMMMyyyyhh:mm:sszzz");sdf.setTimeZone(gmtTz);mh.put("Date",sdf.format(curDate));mh.put("Server","JavaCompleteReference/"+version);mh.put("Content-Type",type);if(length>=0)mh.put("Content-Length",String.valueOf(length));returnmh;}privateStringerror(intcode,Stringmsg,Stringurl){Stringhtml_page=""+CRLF+"

    "+code+""+msg+"

    "+CRLF;if(url!=null)html_page+="ErrorwhenfetchingURL:"+url+CRLF;html_page+=""+CRLF;MimeHeadermh=makeMimeHeader(mime_text_html,html_page.length());HttpResponsehr=newHttpResponse(code,msg,mh);logEntry("GET",url,code,0);returnhr+html_page;}//Read'in'untilyougettwo

    33'sinarow.//ReturnuptothatpointasaString.//Discardall\r's.

    34----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方privateStringgetRawRequest(InputStreamin)throwsIOException{bytebuf[]=newbyte[buffer_size];intpos=0;intc;while((c=in.read())!=-1){switch(c){case'\r':break;case'

    35':if(buf[pos-1]==c){returnnewString(buf,0,pos);}default:buf[pos++]=(byte)c;}}returnnull;}staticStringmonths[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};privateStringhost;//fmt02disthesameasC'sprintf("%02d",i)privatefinalStringfmt02d(inti){if(i<0){i=-i;return((i<9)?"-0":"-")+i;}else{return((i<9)?"0":"")+i;}}privatevoidlogEntry(Stringcmd,Stringurl,intcode,intsize){Calendarcalendar=Calendar.getInstance();inttzmin=calendar.get(Calendar.ZONE_OFFSET)/(60*1000);inttzhour=tzmin/60;tzmin-=tzhour*60;log.log(host+"--["+fmt02d(calendar.get(Calendar.DATE))+"/"+months[calendar.get(Calendar.MONTH)]+"/"+calendar.get(Calendar.YEAR)+":"+fmt02d(calendar.get(Calendar.HOUR))+":"+fmt02d(calendar.get(Calendar.MINUTE))+":"+fmt02d(calendar.get(Calendar.SECOND))+""+fmt02d(tzhour)+fmt02d(tzmin)+"]\""+cmd+""+url+"HTTP/1.0\""+code+""+size+"

    36");

    37----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方hits_served++;bytes_served+=size;}privatevoidwriteString(OutputStreamout,Strings)throwsIOException{out.write(toBytes(s));}privatevoidwriteUCE(OutputStreamout,UrlCacheEntryuce)throwsIOException{HttpResponsehr=newHttpResponse(200,"OK",uce.mh);writeString(out,hr.toString());out.write(uce.data,0,uce.length);logEntry("GET",uce.url,200,uce.length);}privatebooleanserveFromCache(OutputStreamout,Stringurl)throwsIOException{UrlCacheEntryuce;if((uce=(UrlCacheEntry)cache.get(url))!=null){writeUCE(out,uce);hits_to_cache++;returntrue;}returnfalse;}privateUrlCacheEntryloadFile(InputStreamin,Stringurl,MimeHeadermh)throwsIOException{UrlCacheEntryuce;bytefile_buf[]=newbyte[buffer_size];uce=newUrlCacheEntry(url,mh);intsize=0;intn;while((n=in.read(file_buf))>=0){uce.append(file_buf,n);size+=n;}in.close();cache.put(url,uce);files_in_cache++;bytes_in_cache+=uce.length;returnuce;}privateUrlCacheEntryreadFile(Filef,Stringurl)throwsIOException{if(!f.exists())returnnull;

    38----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方InputStreamin=newFileInputStream(f);intfile_length=in.available();Stringmime_type=fnameToMimeType(url);MimeHeadermh=makeMimeHeader(mime_type,file_length);UrlCacheEntryuce=loadFile(in,url,mh);returnuce;}privatevoidwriteDiskCache(UrlCacheEntryuce)throwsIOException{Stringpath=docRoot+uce.url;Stringdir=path.substring(0,path.lastIndexOf("/"));dir.replace('/',File.separatorChar);newFile(dir).mkdirs();FileOutputStreamout=newFileOutputStream(path);out.write(uce.data,0,uce.length);out.close();}//Aclientasksusforaurlthatlookslikethis://http://the.internet.site/the/url//wegogetitfromthesiteandreturnit...privatevoidhandleProxy(OutputStreamout,Stringurl,MimeHeaderinmh){try{intstart=url.indexOf("://")+3;intpath=url.indexOf('/',start);Stringsite=url.substring(start,path).toLowerCase();intport=80;Stringserver_url=url.substring(path);intcolon=site.indexOf(':');if(colon>0){port=Integer.parseInt(site.substring(colon+1));site=site.substring(0,colon);}url="/cache/"+site+((port!=80)?(":"+port):"")+server_url;if(url.endsWith("/"))url+=indexfile;if(!serveFromCache(out,url)){if(readFile(newFile(docRoot+url),url)!=null){serveFromCache(out,url);return;}//Ifwehaven'talreadycachedthispage,openasocket//tothesite'sportandsendaGETcommandtoit.//Wemodifytheuser-agenttoaddourselves..."via".Socketserver=newSocket(site,port);InputStreamserver_in=server.getInputStream();

    39----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方OutputStreamserver_out=server.getOutputStream();inmh.put("User-Agent",inmh.get("User-Agent")+"viaJavaCompleteReferenceProxy/"+version);Stringreq="GET"+server_url+"HTTP/1.0"+CRLF+inmh+CRLF;writeString(server_out,req);Stringraw_request=getRawRequest(server_in);HttpResponseserver_response=newHttpResponse(raw_request);writeString(out,server_response.toString());if(server_response.statusCode==200){UrlCacheEntryuce=loadFile(server_in,url,server_response.mh);out.write(uce.data,0,uce.length);writeDiskCache(uce);logEntry("GET",site+server_url,200,uce.length);}server_out.close();server.close();}}catch(IOExceptione){log.log("Exception:"+e);}}privatevoidhandleGet(OutputStreamout,Stringurl,MimeHeaderinmh){bytefile_buf[]=newbyte[buffer_size];Stringfilename=docRoot+url+(url.endsWith("/")?indexfile:"");try{if(!serveFromCache(out,url)){Filef=newFile(filename);if(!f.exists()){writeString(out,error(404,"NotFound",filename));return;}if(!f.canRead()){writeString(out,error(404,"PermissionDenied",filename));return;}UrlCacheEntryuce=readFile(f,url);writeUCE(out,uce);}}catch(IOExceptione){log.log("Exception:"+e);}}privatevoiddoRequest(Sockets)throwsIOException{if(stopFlag)return;InputStreamin=s.getInputStream();

    40----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方OutputStreamout=s.getOutputStream();Stringrequest=getRawRequest(in);intfsp=request.indexOf('');intnsp=request.indexOf('',fsp+1);inteol=request.indexOf('

    41');Stringmethod=request.substring(0,fsp);Stringurl=request.substring(fsp+1,nsp);Stringraw_mime_header=request.substring(eol+1);MimeHeaderinmh=newMimeHeader(raw_mime_header);request=request.substring(0,eol);if(method.equalsIgnoreCase("get")){if(url.indexOf("://")>=0){handleProxy(out,url,inmh);}else{handleGet(out,url,inmh);}}else{writeString(out,error(405,"MethodNotAllowed",method));}in.close();out.close();}publicvoidrun(){try{ServerSocketacceptSocket;acceptSocket=newServerSocket(port);while(true){Sockets=acceptSocket.accept();host=s.getInetAddress().getHostName();doRequest(s);s.close();}}catch(IOExceptione){log.log("acceptloopIOException:"+e+"

    42");}catch(Exceptione){log.log("Exception:"+e);}}privateThreadt;publicsynchronizedvoidstart(){stopFlag=false;if(t==null){t=newThread(this);t.start();}}publicsynchronizedvoidstop(){

    43----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方stopFlag=true;log.log("Stoppedat"+newDate()+"

    44");}publichttpd(intp,Stringdr,LogMessagelm){port=p;docRoot=dr;log=lm;}//Thismainandlogmethodallowhttpdtoberunfromtheconsole.publicstaticvoidmain(Stringargs[]){httpdh=newhttpd(80,"c:\\www",null);h.log=h;h.start();try{Thread.currentThread().join();}catch(InterruptedExceptione){};}publicvoidlog(Stringm){System.out.print(m);}}HTTP.java這里是一個(gè)給HTTP服務(wù)器一個(gè)“前面板”功能的applet類。該applet有兩個(gè)可以用來(lái)配置服務(wù)器的參數(shù):port和docroot。這是一個(gè)很簡(jiǎn)單的小應(yīng)用程序。它創(chuàng)建了一個(gè)httpd實(shí)例,把它作為L(zhǎng)ogMessage接口傳入自己。然后創(chuàng)建了兩個(gè)面板。一個(gè)面板在頂部有一個(gè)簡(jiǎn)單的標(biāo)簽,在中部是一個(gè)TextArea文本區(qū)以顯示LogMessage;另一個(gè)面板在底部有兩個(gè)按鈕及一個(gè)標(biāo)簽。小應(yīng)用程序的start(?)和stop(?)方法調(diào)用httpd相應(yīng)的方法。標(biāo)注有“Start”和“Stop”的按鈕調(diào)用httpd中它們相應(yīng)的方法。在任何時(shí)候只要一條消息被記錄,右下角的Label對(duì)象就更新,這樣它包含httpd最新的統(tǒng)計(jì)數(shù)據(jù)。importjava.util.*;importjava.applet.*;importjava.awt.*;importjava.awt.event.*;publicclassHTTPextendsAppletimplementsLogMessage,ActionListener{privateintm_port=80;privateStringm_docroot="c:\\www";privatehttpdm_httpd;privateTextAream_log;privateLabelstatus;privatefinalStringPARAM_port="port";privatefinalStringPARAM_docroot="docroot";

    45----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方publicHTTP(){}publicvoidinit(){setBackground(Color.white);Stringparam;//port:Portnumbertolistenonparam=getParameter(PARAM_port);if(param!=null)m_port=Integer.parseInt(param);//docroot:webdocumentrootparam=getParameter(PARAM_docroot);if(param!=null)m_docroot=param;setLayout(newBorderLayout());Labellab=newLabel("JavaHTTPD");lab.setFont(newFont("SansSerif",Font.BOLD,18));add("North",lab);m_log=newTextArea("",24,80);add("Center",m_log);Panelp=newPanel();p.setLayout(newFlowLayout(FlowLayout.CENTER,1,1));add("South",p);Buttonbstart=newButton("Start");bstart.addActionListener(this);p.add(bstart);Buttonbstop=newButton("Stop");bstop.addActionListener(this);p.add(bstop);status=newLabel("raw");status.setForeground(Color.green);status.setFont(newFont("SansSerif",Font.BOLD,10));p.add(status);m_httpd=newhttpd(m_port,m_docroot,this);}publicvoiddestroy(){stop();}publicvoidpaint(Graphicsg){}publicvoidstart(){m_httpd.start();status.setText("Running");clear_log("Logstartedon"+newDate()+"

    46");

    47----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方}publicvoidstop(){m_httpd.stop();status.setText("Stopped");}publicvoidactionPerformed(ActionEventae){Stringlabel=ae.getActionCommand();if(label.equals("Start")){start();}else{stop();}}publicvoidclear_log(Stringmsg){m_log.setText(msg+"

    48");}publicvoidlog(Stringmsg){m_log.append(msg);status.setText(m_httpd.hits_served+"hits("+(m_httpd.bytes_served/1024)+"K),"+m_httpd.files_in_cache+"cachedfiles("+(m_httpd.bytes_in_cache/1024)+"K),"+m_httpd.hits_to_cache+"cachedhits");status.setSize(status.getPreferredSize());}}注意:httpd.java和HTTP.java文件中,代碼是在假定文件根部是“c:\www”的基礎(chǔ)上建立的。你可能需要改變配置的值。因?yàn)檫@個(gè)小應(yīng)用程序?qū)懭胍粋€(gè)日志文件,它只能在被信任的條件下工作。例如,一個(gè)小應(yīng)用程序在它可以獲得用戶CLASSPATH時(shí)被信任。18.9數(shù)據(jù)報(bào)對(duì)于你的大多數(shù)網(wǎng)絡(luò)需求,你會(huì)對(duì)TCP/IP型網(wǎng)絡(luò)很滿意。它提供了有序的、可預(yù)測(cè)和可靠的信息包數(shù)據(jù)流。但是,這樣做的代價(jià)也很大。TCP包含很多在擁擠的網(wǎng)絡(luò)中處理?yè)砣刂频膹?fù)雜算法以及信息丟失的悲觀的預(yù)測(cè)。這導(dǎo)致了一個(gè)效率很差的傳輸數(shù)據(jù)方式。數(shù)據(jù)報(bào)是一種可選的替換方法。數(shù)據(jù)報(bào)(Datagrams)是在機(jī)器間傳遞的信息包,它有些像從一個(gè)訓(xùn)練有素但是很盲目的捕手投出一記有力的傳球給三壘。一旦數(shù)據(jù)報(bào)被釋放給它們預(yù)定的目標(biāo),不保證它們一定到達(dá)目的地,甚至不保證一定存在數(shù)據(jù)的接收者。同樣,數(shù)據(jù)報(bào)被接受時(shí),不保證它在傳輸過(guò)程不受損壞,不保證發(fā)送它的機(jī)器仍在那兒等待響應(yīng)。Java通過(guò)兩個(gè)類實(shí)現(xiàn)UDP協(xié)議頂層的數(shù)據(jù)報(bào):DatagramPacket對(duì)象是數(shù)據(jù)容器,

    49----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方DatagramSocket是用來(lái)發(fā)送和接受DatagramPackets的機(jī)制。18.9.1DatagramPacketDatagramPackets可以用四個(gè)構(gòu)造函數(shù)中的一個(gè)創(chuàng)建。第一個(gè)構(gòu)造函數(shù)指定了一個(gè)接收數(shù)據(jù)的緩沖區(qū)和信息包的容量大小。它通過(guò)DatagramSocket接收數(shù)據(jù)。第二種形式允許你在存儲(chǔ)數(shù)據(jù)的緩沖區(qū)中指定一個(gè)偏移量。第三種形式指定了一個(gè)用于DatagramSocket決定信息包將被送往何處的目標(biāo)地址和端口。第四種形式從數(shù)據(jù)中指定的偏移量位置開(kāi)始傳輸數(shù)據(jù)包。想象前兩種形式是建立在“盒內(nèi)”的,后兩種形式形成了填塞物,并為一個(gè)信封注明了地址。下面是四個(gè)構(gòu)造函數(shù):DatagramPacket(bytedata[],intsize)DatagramPacket(bytedata[],intoffset,intsize)DatagramPacket(bytedata[],intsize,InetAddressipAddress,intport)DatagramPacket(bytedata[],intoffset,intsize,InetAddressipAddress,intport)存在幾種方法可獲取DatagramPacket內(nèi)部狀態(tài)。它們對(duì)信息包的目標(biāo)地址和端口號(hào)以及原始數(shù)據(jù)和數(shù)據(jù)長(zhǎng)度有完全的使用權(quán),下面是它們的概述:InetAddressgetAddress(?)返回目標(biāo)文件InetAddress,一般用于發(fā)送。IntgetPort(?)返回端口號(hào)。byte[]getData(?)返回包含在數(shù)據(jù)包中的字節(jié)數(shù)組數(shù)據(jù)。多用于在接收數(shù)據(jù)之后從數(shù)據(jù)包來(lái)檢索數(shù)據(jù)。IntgetLength(?)返回包含在將從getData(?)方法返回的字節(jié)數(shù)組中有效數(shù)據(jù)長(zhǎng)度。通常它與整個(gè)字節(jié)數(shù)組長(zhǎng)度不等。18.9.2數(shù)據(jù)報(bào)服務(wù)器和客戶下面的例子實(shí)現(xiàn)了一個(gè)非常簡(jiǎn)單的聯(lián)網(wǎng)通信的客戶和服務(wù)器。消息被寫入服務(wù)器的窗口并通過(guò)網(wǎng)絡(luò)寫入客戶端,在此它們被顯示。//DemonstrateDatagrams.importjava.net.*;classWriteServer{publicstaticintserverPort=666;publicstaticintclientPort=999;publicstaticintbuffer_size=1024;publicstaticDatagramSocketds;publicstaticbytebuffer[]=newbyte[buffer_size];publicstaticvoidTheServer()throwsException{intpos=0;while(true){intc=System.in.read();switch(c){

    50----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方case-1:System.out.println("ServerQuits.");return;case'\r':break;case'

    51':ds.send(newDatagramPacket(buffer,pos,InetAddress.getLocalHost(),clientPort));pos=0;break;default:buffer[pos++]=(byte)c;}}}publicstaticvoidTheClient()throwsException{while(true){DatagramPacketp=newDatagramPacket(buffer,buffer.length);ds.receive(p);System.out.println(newString(p.getData(),0,p.getLength()));}}publicstaticvoidmain(Stringargs[])throwsException{if(args.length==1){ds=newDatagramSocket(serverPort);TheServer();}else{ds=newDatagramSocket(clientPort);TheClient();}}}該程序被DatagramSocket構(gòu)造函數(shù)限制在本地機(jī)的兩個(gè)端口間運(yùn)行。試著運(yùn)行該程序,在一個(gè)窗口中鍵入javaWriteServer這是在客戶端的。然后運(yùn)行javaWriteServer1這是在服務(wù)器端的。在服務(wù)器窗口中打印的任何東西在接受回車之后將被送到客戶窗口。注意:該例題需要你的計(jì)算機(jī)與Internet相連。

    52----------專業(yè)最好文檔,專業(yè)為你服務(wù),急你所急,供你所需-------------文檔下載最佳的地方18.10網(wǎng)絡(luò)價(jià)值給你5個(gè)類InetAddress,Socket,ServerSocket,DatagramSocket和DatagramPacket,你可以編寫現(xiàn)有的任何Internet協(xié)議。它們同樣為Internet連接提供功能強(qiáng)大的低級(jí)控制。Java的網(wǎng)絡(luò)包也完美地反映了Internet的狀態(tài)。

    當(dāng)前文檔最多預(yù)覽五頁(yè),下載文檔查看全文

    此文檔下載收益歸作者所有

    當(dāng)前文檔最多預(yù)覽五頁(yè),下載文檔查看全文
    溫馨提示:
    1. 部分包含數(shù)學(xué)公式或PPT動(dòng)畫(huà)的文件,查看預(yù)覽時(shí)可能會(huì)顯示錯(cuò)亂或異常,文件下載后無(wú)此問(wèn)題,請(qǐng)放心下載。
    2. 本文檔由用戶上傳,版權(quán)歸屬用戶,天天文庫(kù)負(fù)責(zé)整理代發(fā)布。如果您對(duì)本文檔版權(quán)有爭(zhēng)議請(qǐng)及時(shí)聯(lián)系客服。
    3. 下載前請(qǐng)仔細(xì)閱讀文檔內(nèi)容,確認(rèn)文檔內(nèi)容符合您的需求后進(jìn)行下載,若出現(xiàn)內(nèi)容與標(biāo)題不符可向本站投訴處理。
    4. 下載文檔時(shí)可能由于網(wǎng)絡(luò)波動(dòng)等原因無(wú)法下載或下載錯(cuò)誤,付費(fèi)完成后未能成功下載的用戶請(qǐng)聯(lián)系客服處理。
    大家都在看
    近期熱門
    相關(guān)標(biāo)簽
    關(guān)閉