第3章線程和網(wǎng)絡編程_第1頁
第3章線程和網(wǎng)絡編程_第2頁
第3章線程和網(wǎng)絡編程_第3頁
第3章線程和網(wǎng)絡編程_第4頁
第3章線程和網(wǎng)絡編程_第5頁
已閱讀5頁,還剩84頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第三章

線程和網(wǎng)絡編程南京郵電大學通信與信息工程學院王誠wangc@Java實用編程技術與項目實戰(zhàn)在操作系統(tǒng)中都會涉及處理機管理,即會引入一個進程的概念,它是動態(tài)的、相互隔離的、獨立運行的、是資源分配單位及調(diào)度的基本單位進程是由進程控制塊、程序段、數(shù)據(jù)段三部分組成線程是共存于一個進程中的多個并發(fā)執(zhí)行流Java是第一個在語言本身中顯式地包含線程的主流編程語言,而不是對底層操作系統(tǒng)的調(diào)用線程概念Java實用編程技術與項目實戰(zhàn)進程與線程是有區(qū)別的。進程(process)本質上是一個并發(fā)執(zhí)行的程序。因此,基于進程(process-based)的多任務處理的特點是允許你的計算機同時運行兩個或更多的程序?;诰€程(thread-based)的多任務處理環(huán)境中,線程是最小的執(zhí)行單位,線程也稱輕量級進程,共享進程的內(nèi)存、文件句柄、和狀態(tài),單線程具有自己的堆棧、自己的程序計數(shù)器和自己的局部變量線程概念Java實用編程技術與項目實戰(zhàn)多線程主要是為了節(jié)約CPU時間。多線程程序比多進程程序需要更少的管理費用。進程是重量級的任務,需要分配它們自己獨立的地址空間。進程間通信是昂貴和受限的。進程間的轉換也是很需要花費的,即進程切換需要花費大量處理機時間。而線程是輕量級的任務,共享相同的地址空間并且共同分享同一個進程。線程間通信是便宜的,線程間的切換也是低成本的線程概念Java實用編程技術與項目實戰(zhàn)Java運行系統(tǒng)在很多方面依賴于線程,所有的類庫設計都考慮到多線程。實際上,Java使用線程來使整個環(huán)境異步。這有利于通過防止CPU循環(huán)的浪費來減少無效部分Java是多線程處理模型。其優(yōu)點在于取消了主循環(huán)/輪詢機制。一個線程可以暫停而不影響程序的其他部分,即多個線程通過系統(tǒng)調(diào)度進行并發(fā)執(zhí)行。在Java程序中出現(xiàn)線程阻塞,僅有一個線程暫停,其他線程繼續(xù)運行Java線程模型Java實用編程技術與項目實戰(zhàn)每個線程都有產(chǎn)生、運行、消亡的狀態(tài)轉換過程Java線程模型Java實用編程技術與項目實戰(zhàn)創(chuàng)建狀態(tài)(newThread):執(zhí)行下列語句時,線程就處于創(chuàng)建狀態(tài):ThreadmyThread=newMyThreadClass();當一個線程處于創(chuàng)建狀態(tài)時,它僅僅是一個空的線程對象,系統(tǒng)不為它分配資源,尚未執(zhí)行(start()尚未調(diào)用)可運行狀態(tài)(Runnable):當一個線程處于可運行狀態(tài)時,系統(tǒng)為這個線程分配了它需的系統(tǒng)資源,安排其運行并調(diào)用線程運行方法,這樣就使得該線程處于可運行(Runnable)狀態(tài)。如執(zhí)行:ThreadmyThread=newMyThreadClass();myThread.start();Java線程模型Java實用編程技術與項目實戰(zhàn)不可運行狀態(tài)(NotRunnable):不可運行狀態(tài)也稱為阻塞狀態(tài)(Blocked)。因為某種原因(輸入/輸出、等待消息或其它阻塞情況),系統(tǒng)不能執(zhí)行線程的狀態(tài)。這時即使處理器空閑,也不能執(zhí)行該線程。進入不可運行狀態(tài)的原因有如下幾條:調(diào)用了sleep()方法;調(diào)用了suspend()方法;為等候一個條件變量,線程調(diào)用wait()方法;輸入輸出流中發(fā)生線程阻塞。Java線程模型Java實用編程技術與項目實戰(zhàn)死亡狀態(tài)(Dead):線程的終止一般可通過兩種方法實現(xiàn):自然撤消(線程執(zhí)行完)或是被停止(調(diào)用stop()方法)。不推薦通過調(diào)用stop()來終止線程的執(zhí)行,而是讓線程執(zhí)行完Java線程模型Java實用編程技術與項目實戰(zhàn)Java的多線程系統(tǒng)建立于Thread類。Thread類封裝了線程的執(zhí)行。為創(chuàng)建一個新的線程,你的程序必須擴展Thread或實現(xiàn)Runnable接口Thread類方法如下表:Java線程模型Java實用編程技術與項目實戰(zhàn)Java線程模型方法意義getName 獲得線程名稱getPriority 獲得線程優(yōu)先級jsAlive 判定線程是否仍在運行join 等待一個線程終止run 線程的入口點.sleep 在一段時間內(nèi)掛起線程start 通過調(diào)用運行方法來啟動線程Java實用編程技術與項目實戰(zhàn)Java程序至少包含一個線程,即當Java程序啟動時,一個線程立刻運行,該線程通常叫做程序的主線程(mainthread),因為它是程序開始時就執(zhí)行的。主線程的重要性體現(xiàn)在兩方面:它是產(chǎn)生其他子線程的線程;通常它必須最后完成執(zhí)行,因為它執(zhí)行各種關閉動作主線程Java實用編程技術與項目實戰(zhàn)盡管主線程在程序啟動時自動創(chuàng)建,但它可以由一個Thread對象控制。為此,你必須調(diào)用方法currentThread()獲得它的一個引用,currentThread()是Thread類的公有的靜態(tài)成員。它的通常形式如下:staticThreadcurrentThread()該方法返回一個調(diào)用它的線程的引用。一旦獲得主線程的引用,就可以像控制其他線程那樣控制主線程主線程Java實用編程技術與項目實戰(zhàn)publicclassTest{ publicstaticvoidmain(Stringargs[]) { Threadct=Thread.currentThread(); System.out.println("Currentthread:"+ct); ct.setName("Test"); System.out.println("Afternamechange:"+ct); try { Thread.sleep(1000); } catch(InterruptedExceptione) { System.out.println("Mainthreadinterrupted"); } }}主線程Java實用編程技術與項目實戰(zhàn)程序的運行結果:Currentthread:Thread[main,5,main]Afternamechange:Thread[Test,5,main]主線程Java實用編程技術與項目實戰(zhàn)大多數(shù)情況,通過實例化一個Thread對象來創(chuàng)建一個線程。Java定義了兩種方式:實現(xiàn)Runnable接口和繼承Thread類創(chuàng)建線程的最簡單的方法就是創(chuàng)建一個實現(xiàn)Runnable接口的類。Runnable抽象了一個執(zhí)行代碼單元。你可以通過實現(xiàn)Runnable接口的方法創(chuàng)建每一個對象的線程。為實現(xiàn)Runnable接口,一個類僅需實現(xiàn)一個run()的簡單方法創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)在run()中可以定義代碼來構建新的線程。理解下面內(nèi)容是至關重要的:run()方法能夠像主線程那樣調(diào)用其他方法,引用其他類,聲明變量。僅有的不同是run()在程序中確立另一個并發(fā)的線程執(zhí)行入口。當run()返回時,該線程結束創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)classChildimplementsRunnable{ Threadt; Child() { t=newThread(this,"ChildtThread"); System.out.println("Childthread:"+t); t.start(); }創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)

publicvoidrun() { try { for(inti=5;i>0;i--) { System.out.println("ChildThread:"+i); Thread.sleep(500); } } catch(InterruptedExceptione) { System.out.println("Childinterrupted."); } System.out.println("Exitingchildthread."); }}創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)publicclassTest{ publicstaticvoidmain(Stringargs[]) { newChild(); try { for(inti=5;i>0;i--) { System.out.println("MainThread:"+i); Thread.sleep(1000); } } catch(InterruptedExceptione) { System.out.println("Mainthreadinterrupted."); } System.out.println("Mainthreadexiting."); }}創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)該程序的輸出如下:Childthread:Thread[ChildtThread,5,main]MainThread:5ChildThread:5ChildThread:4MainThread:4ChildThread:3ChildThread:2MainThread:3ChildThread:1Exitingchildthread.MainThread:2MainThread:1Mainthreadexiting創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)創(chuàng)建線程的另一個途徑是創(chuàng)建一個新類來擴展Thread類,然后創(chuàng)建該類的實例。當一個類繼承Thread時,它必須重載run()方法,這個run()方法是新線程的入口。它也必須調(diào)用start()方法去啟動新線程執(zhí)行創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)classMythreadextendsThread{ Mythread() { super("DemoThread"); System.out.println("Childthread:"+this); start(); }創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)publicvoidrun() { try { for(inti=5;i>0;i--) { System.out.println("ChildThread:"+i); Thread.sleep(500); } } catch(InterruptedExceptione) { System.out.println("Childinterrupted."); } System.out.println("Exitingchildthread."); }}創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)publicclassTest{ publicstaticvoidmain(Stringargs[]) { newMythread(); try { for(inti=5;i>0;i--) { System.out.println("MainThread:"+i); Thread.sleep(1000); } } catch(InterruptedExceptione) { System.out.println("Mainthreadinterrupted."); } System.out.println("Mainthreadexiting."); }}創(chuàng)建線程Java實用編程技術與項目實戰(zhàn)當兩個或兩個以上的線程需要共享資源,它們需要某種方法來確定資源在某一刻僅被一個線程占用。達到此目的的過程叫做同步(synchronization)。在某些情況中,您不必用同步來將數(shù)據(jù)從一個線程傳遞到另一個,因為JVM已經(jīng)隱含地為您執(zhí)行同步,如:由靜態(tài)初始化器(在靜態(tài)字段上或static{}塊中的初始化器)初始化數(shù)據(jù)時;訪問final字段時;在創(chuàng)建線程之前創(chuàng)建對象時等線程同步概念Java實用編程技術與項目實戰(zhàn)如果沒有同步,數(shù)據(jù)很容易就處于不一致狀態(tài)。例如,如果一個線程正在更新兩個相關值(比如,粒子的位置和速率),而另一個線程正在讀取這兩個值,有可能在第一個線程只寫了一個值,還沒有寫另一個值的時候,調(diào)度第二個線程運行,這樣它就會看到一個舊值和一個新值。同步讓我們可以定義必須原子地運行的代碼塊,這樣對于其他線程而言,它們要么都執(zhí)行,要么都不執(zhí)行線程同步概念Java實用編程技術與項目實戰(zhàn)同步的關鍵是管程(也叫信號量semaphore)的概念。管程是一個互斥獨占鎖定的對象,或稱互斥體(mutex)。在給定的時間,僅有一個線程可以獲得管程。當一個線程需要鎖定,它必須進入管程。所有其他的試圖進入已經(jīng)鎖定的管程的線程必須掛起直到第一個線程退出管程。這些其他的線程被稱為等待管程。一個擁有管程的線程如果愿意的話可以再次進入相同的管程線程同步概念Java實用編程技術與項目實戰(zhàn)Java中同步是簡單的,因為所有對象都有它們與之對應的隱式管程。進入某一對象的管程,就是調(diào)用被synchronized關鍵字修飾的方法。當一個線程在一個同步方法內(nèi)部,所有試圖調(diào)用該方法(或其他同步方法)的同實例的其他線程必須等待。為了退出管程,并放棄對對象的控制權給其他等待的線程,擁有管程的線程僅需從同步方法中返回線程同步概念Java實用編程技術與項目實戰(zhàn)classCallme{ voidcall(Stringmsg) { System.out.print("["+msg); try { Thread.sleep(1000); } catch(InterruptedExceptione) { System.out.println("Interrupted"); } System.out.println("]"); }}線程同步概念Java實用編程技術與項目實戰(zhàn)classCallerimplementsRunnable{ Stringmsg; Callmetarget; Threadt; publicCaller(Callmetarg,Strings) { target=targ; msg=s; t=newThread(this); t.start(); }線程同步概念Java實用編程技術與項目實戰(zhàn)classCallerimplementsRunnable{ Stringmsg; Callmetarget; Threadt; publicCaller(Callmetarg,Strings) { target=targ; msg=s; t=newThread(this); t.start(); }publicvoidrun() { target.call(msg); }}線程同步概念Java實用編程技術與項目實戰(zhàn)publicclassTest{ publicstaticvoidmain(Stringargs[]) { Callmetarget=newCallme(); Callerob1=newCaller(target,"Hello"); Callerob2=newCaller(target,"Synchronized"); Callerob3=newCaller(target,"World"); try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedExceptione) { System.out.println("Interrupted"); } }}線程同步概念Java實用編程技術與項目實戰(zhàn)該程序的輸出如下:[Hello[Synchronized[World]]]從輸出看出,結果并非想要的那樣。因為通過調(diào)用sleep(),call()方法允許執(zhí)行轉換到另一個線程。導致該結果是三個消息字符串的混合輸出。如果能夠限制三個線程同時調(diào)用同一對象的同一方法的方法,則可以按照期望的那樣輸出結果線程同步概念Java實用編程技術與項目實戰(zhàn)為達到上例所想達到的目的,必須有權連續(xù)的使用call()。也就是說,在某一時刻,必須限制只有一個線程可以支配它。為此,你只需在call()定義前加上關鍵字synchronized,如下:synchronizedvoidcall(Stringmsg)線程同步概念Java實用編程技術與項目實戰(zhàn)保證了在一個線程使用call()時其他線程進入call()。在synchronized加到call()前面以后,程序輸出如下:[Hello][Synchronized][World]線程同步概念Java實用編程技術與項目實戰(zhàn)前面的例子都無條件的阻塞了其他線程異步訪問某個方法。多線程通過把任務分成離散的和合乎邏輯的單元代替了事件循環(huán)程序Java包含了通過wait(),notify()和notifyAll()方法實現(xiàn)的一個進程間通信機制wait()告知被調(diào)用的線程放棄管程進入睡眠直到其他線程進入相同管程并且調(diào)notify()。notify()恢復相同對象中第一個調(diào)用wait()的線程。notifyAll()恢復相同對象中所有調(diào)用wait()的線程。具有最高優(yōu)先級的線程最先運行線程通信Java實用編程技術與項目實戰(zhàn)下面的例子程序錯誤的實行了一個簡單生產(chǎn)者/消費者的問題。它由四個類組成:Q(隊列,模擬取數(shù)據(jù)、存數(shù)據(jù));Producer(生產(chǎn)者線程對象);Consumer(消費者線程對象);以及主程序類線程通信Java實用編程技術與項目實戰(zhàn)classQ{intn;booleanvalueSet=false;synchronizedintget(){

if(!valueSet)

try

{

wait();

}

catch(InterruptedExceptione)

{

System.out.println("InterruptedExceptioncaught");

}

System.out.println("Got:"+n);

valueSet=false;

notify();

returnn;}線程通信Java實用編程技術與項目實戰(zhàn)synchronizedvoidput(intn){

if(valueSet)

try

{

wait();

}

catch(InterruptedExceptione)

{

System.out.println("InterruptedExceptioncaught");

}

this.n=n;

valueSet=true;

System.out.println("Put:"+n);

notify();}}線程通信Java實用編程技術與項目實戰(zhàn)classProducerimplementsRunnable{Qq;

Producer(Qq){

this.q=q;

newThread(this,"Producer").start();}線程通信Java實用編程技術與項目實戰(zhàn)publicvoidrun(){

inti=0;

while(true)

{

q.put(i++);

}}}classConsumerimplementsRunnable{Qq;

Consumer(Qq)

{

this.q=q;

newThread(this,"Consumer").start();}線程通信Java實用編程技術與項目實戰(zhàn)publicvoidrun(){

while(true)

{

q.get();

}}}publicclassTest{publicstaticvoidmain(Stringargs[]){

Qq=newQ();

newProducer(q);

newConsumer(q);

System.out.println("PressControl-Ctostop.");}}線程通信Java實用編程技術與項目實戰(zhàn)下面是該程序的輸出,它清楚地顯示了同步行為:Put:1Got:1Put:2Got:2Put:3Got:3Put:4Got:4Put:5Got:5

線程通信Java實用編程技術與項目實戰(zhàn)網(wǎng)絡編程技術是當前一種主流的編程技術,隨著互聯(lián)網(wǎng)趨勢的逐步增強以及網(wǎng)絡應用程序的大量出現(xiàn),網(wǎng)絡編程技術在實際的開發(fā)中獲得了大量的使用。網(wǎng)絡編程的實質就是兩個(或多個)設備(例如計算機)之間的數(shù)據(jù)傳輸。TCP(TransmissionControlProtocol),指的是傳輸控制協(xié)議,它是主要負責數(shù)據(jù)的分組和重組。在簡化的計算機網(wǎng)絡OSI模型中,它完成第四層傳輸層所指定的功能TCP是一個“可靠的”、面向連結的傳輸機制,通過三次握手建立連接。它提供一種可靠的字節(jié)流保證數(shù)據(jù)完整、無損并且按順序到達網(wǎng)絡編程基礎TCP協(xié)議Java實用編程技術與項目實戰(zhàn)UDP(UserDatagramProtocol)指的是用戶數(shù)據(jù)報協(xié)議。和TCP一樣都是網(wǎng)絡傳輸層上的協(xié)議,但與TCP有本質的區(qū)別UDP是“不可靠”、無連結和面向消息的協(xié)議,它使用數(shù)據(jù)報進行傳輸UDP協(xié)議Java實用編程技術與項目實戰(zhàn)端口(Port)可以被理解成計算機與外界通信交流的窗戶。網(wǎng)絡上的一臺計算機可以提供多種服務,單靠IP地址無法將它們區(qū)別開,所以通過“IP地址+端口號”的形式來區(qū)分不同的服務端口號是一個整數(shù),通常范圍在0~65535。小于1024的端口號一般的分配給特定的服務協(xié)議的端口Java實用編程技術與項目實戰(zhàn)套接字,是支持TCP/IP的網(wǎng)絡通信的基本操作單元,可以看成在兩個程序進行通訊連接中的一個端點,是連接應用程序和網(wǎng)絡驅動程序的橋梁,Socket在應用程序中創(chuàng)建,通過綁定與網(wǎng)絡驅動建立關系通常用的TCP/IP協(xié)議的3種套接字類型有

流套接字(SOCK_STREAM)、數(shù)據(jù)報套接字(SOCK_DGRAM)、原始套接字(SOCK_RAW)流套接字用于提供面向連接、可靠的數(shù)據(jù)傳輸服務數(shù)據(jù)報套接字(SOCK_DGRAM):數(shù)據(jù)報套接字提供了一種無連接的服務原始套接字(SOCK_RAW):原始套接字可以讀寫內(nèi)核沒有處理的IP數(shù)據(jù)包套接字Java實用編程技術與項目實戰(zhàn)C/S(Client/Server,客戶機/服務器)模式又稱C/S結構,是20世紀80年代末逐步成長起來的一種模式,是軟件系統(tǒng)體系結構的一種C/S結構的關鍵在于功能的分布,一些功能放在前端機(即客戶機)上執(zhí)行,另一些功能放在后端機(即服務器)上執(zhí)行在Berkeley套接字中,套接字的概念允許單個計算機同時服務于很多不同的客戶,并能夠提供不同類型信息的服務客戶機/服務器的通信基于套結字。套結字是internet通信的端點??梢岳斫鉃槭强蛻魴C和服務器之間的兩端客戶/服務器模式Java實用編程技術與項目實戰(zhàn)客戶程序創(chuàng)建客戶套接字,服務器應用程序創(chuàng)建服務器套接字。雙方的套接字連接起來后,數(shù)據(jù)通過這一連接來交換客戶/服務器模式Java實用編程技術與項目實戰(zhàn)Java通過擴展流式輸入/輸出接口和增加在網(wǎng)絡上建立輸入/輸出對象特性這兩個方法支持TCP/IPJava支持TCP和UDP協(xié)議族Java提供的網(wǎng)絡功能有三大類:URL、Socket、DatagramTCP用于網(wǎng)絡的可靠的流式輸入/輸出。UDP支持更簡單的、快速的、點對點的數(shù)據(jù)報模式JAVA和網(wǎng)絡Java實用編程技術與項目實戰(zhàn)Authenticator(Java2)JarURLConnection(Java2)SocketPermissionContentHandlerMulticastSocketURLDatagramPacketNetPermissionURLClassLoader(Java2)DatagramSocketPasswordAuthentication(Java2)URLConnectionDatagramSocketImplServerSocketURLDecoder(Java2)HttpURLConnectionSocketURLEncoderInetAddressSocketImplURLStreamHandlerJAVA和網(wǎng)絡Java實用編程技術與項目實戰(zhàn)網(wǎng)絡類包所包含的類ContentHandlerFactorySocketImplFactoryURLStreamHandlerFactoryFileNameMapSocketOptionsDatagramSocketImplFactoryJAVA和網(wǎng)絡Java實用編程技術與項目實戰(zhàn)包的接口InetAddress類用來封裝數(shù)字式的IP地址和該地址的域名InetAddress類可以用于標識網(wǎng)絡上的硬件資源,建立IP地址。把IP地址或是DomainName轉換成電腦看得懂的網(wǎng)絡地址InetAddress類沒有明顯的構造方法。為生成一個InetAddress對象,必須運用一個可用的工廠方法InetAddress類Java實用編程技術與項目實戰(zhàn)方法名稱方法說明publicBooleanequals(Objectobj)判斷給定對象是否與當前對象擁有相同的IP地址,相同時,函數(shù)返回true,不同時,返回false。publicbyte[]getAddress()返回當前對象的IP地址publicstaticInetAddress[]getAllByName(Stringhost)throwsUnknownHostException返回給定主機名的資源所在的所有IP地址。publicstaticInetAddressgetByName(Stringhost)throwsUnknownHostException返回給定主機名的主機的IP地址。

InetAddress類Java實用編程技術與項目實戰(zhàn)InetAddress類主要方法方法名稱方法說明publicStringgetHostName()返回當前對象的主機名。publicstaticInetAddressgetLocalHost()throwsUnknownHostException返回本地主機的IP地址。publicinthashCode()返回當前對象的IP地址的散列碼。publicStringtoString()返回當前對象的IP地址的字符串表示。

InetAddress類Java實用編程技術與項目實戰(zhàn)InetAddress類主要方法import.*;publicclassTest{publicstaticvoidmain(Stringargs[])throwsUnknownHostException { InetAddressAddress=InetAddress.getLocalHost(); System.out.println(Address); Address=InetAddress.getByName(""); System.out.println(Address); InetAddressia[]=InetAddress.getAllByName("www."); for(inti=0;i<ia.length;i++) System.out.println(ia[i]); }}

InetAddress類Java實用編程技術與項目實戰(zhàn)URL提供了一個相當容易理解的形式來惟一確定或對Internet上的信息進行編址在Java的網(wǎng)絡類庫中,URL類為用URL在Internet上獲取信息提供了一個簡單的、簡潔的用戶編程接口(API)URL規(guī)范以四個元素為基礎:所用到的協(xié)議、主機名或所用主機的IP地址、端口號、實際的文件路徑URLJava實用編程技術與項目實戰(zhàn)方法名稱方法說明publicURL(Stringaddr)throwsMalformedURLException創(chuàng)建一個給定資源地址的URL對象,這里,addr應是一個合法的URL值。publicURL(Stringprotocol,Stringhost,Stringfile)throwsMalformedURLException創(chuàng)建一個擁有指定協(xié)議名稱、主機名、文件名的URL對象pubicURL(Stringprotocol,Stringhost,intport,Stringfile)throwsMaformedURLException創(chuàng)建一個擁有指定協(xié)議名稱、主機名、端口號、文件名的URL對象publicStringgetProtocol()返回URL中的協(xié)議名稱URLJava實用編程技術與項目實戰(zhàn)URL類的主要方法方法名稱方法說明publicStringgetHost()返回URL中的主機名publicintgetPort()返回URL中的端口號。如果URL中沒有設定端口號,該函數(shù)返回-1。publicStringgetFile()返回URL中的文件名部分publicStringgetRef()返回URL的引用。publicStringtoString()返回整個URL值URLJava實用編程技術與項目實戰(zhàn)URL類的主要方法import.*;publicclassTest{ publicstaticvoidmain(Stringargs[])throwsMalformedURLException { URLhp=newURL("/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()); }}URLJava實用編程技術與項目實戰(zhàn)為獲URL的實際比特或內(nèi)容信息,用它的openConnection()方法從它創(chuàng)建一個URLConnection對象,如下常用形式:URLConnectionopenConnection()它返回一個URLConnection對象。它可能引發(fā)IOException異常URLJava實用編程技術與項目實戰(zhàn)例:用URL對象的openConnection()方法創(chuàng)建了一個URLConnection類,然后用它來檢查文件的屬性和內(nèi)容import.*;importjava.io.*;importjava.util.Date;publicclassTest{ publicstaticvoidmain(Stringargs[])throwsException { intc;URLhp=newURL("");URLConnectionhpCon=hp.openConnection();System.out.println("Date:"+newDate(hpCon.getDate()));System.out.println("Content-Type:"+hpCon.getContentType());URLJava實用編程技術與項目實戰(zhàn)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;while(((c=input.read())!=-1)&&(--i>0))System.out.print((char)c);input.close();}elseSystem.out.println("NoContentAvailable");}}URLJava實用編程技術與項目實戰(zhàn)該程序建立了一個經(jīng)過端口80通向的HTTP連接。然后列出了標頭值并檢索內(nèi)容。下面是輸出的前幾行:Date:FriOct0622:11:12CDT2011Content-Type:text/htmlExpires:0Last-Modified:TueOct2811:16:27CDT2011Content-Length:529Content:<html><head><title>myweb</title></head>URLJava實用編程技術與項目實戰(zhàn)TCP/IP套接字用于在主機和Internet之間建立可靠的、雙向的、持續(xù)的、點對點的流式連接。一個套接字可以用來建立Java的輸入/輸出系統(tǒng)到其他的駐留在本地機或Internet上的任何機器的程序的連接。Java中有兩類TCP套接字,一種是服務器端的,另一種是客戶端的。Socket:客戶端套接字類,為建立連向服務器套接字以及啟動協(xié)議交換而設計。一個Socket對象的創(chuàng)建隱式建立了一個客戶和服務器的連接。沒有顯式的說明建立連接細節(jié)的方法或構造方法。表3.7所示是用來生成客戶套接字的兩個構造方法。TCP編程模型Java實用編程技術與項目實戰(zhàn)生成客戶套接字的兩個構造方法TCP編程模型方法含義Socket(StringhostName,intport)創(chuàng)建一個本地主機與給定名稱的主機端口的套接字連接,可以引發(fā)一個UnknownHostException異?;騃OException異常Socket(InetAddressipAddress,intport)用一個預先存在的InetAddress對象和端口創(chuàng)建一個套接字,可以引發(fā)IOException異常Java實用編程技術與項目實戰(zhàn)方法含義InetAddressgetInetAddress()返回和Socket對象相關的InetAddressIntgetPort()返回與該Socket對象連接的遠程端口IntgetLocalPort()返回與該Socket連接的本地端口TCP編程模型Java實用編程技術與項目實戰(zhàn)地址與端口方法方法含義InputStreamgetInputStream()返回與調(diào)用套接字有關的InputStream類OutputStreamgetOutputStream()返回與調(diào)用套接字有關的OutputStream類voidclose()關閉InputStream和OutputStreamTCP編程模型Java實用編程技術與項目實戰(zhàn)輸入和輸出流方法ServerSocket:服務器端套結字類,設計成在等待客戶建立連接之前不做任何事的“監(jiān)聽器”ServerSocket與通常的Sockets類完全不同。當創(chuàng)建一個ServerSocket類,它在系統(tǒng)注冊自己對客戶連接感興趣ServerSocket的構造方法反映了希望接收連接的端口號及希望排隊等待上述端口的時間。隊列長度告訴系統(tǒng)多少與之連接的客戶在系統(tǒng)拒絕連接之前可以掛起。隊列的默認長度是50TCP編程模型Java實用編程技術與項目實戰(zhàn)方法含義ServerSocket(intport)在指定端口創(chuàng)建隊列長度為50的服務器套接字ServerSocket(intport,intmaxQueue)在指定端口創(chuàng)建一個最大隊列長度為maxQueue的服務器套接字ServerSocket(intport,intmaxQueue,InetAddresslocalAddress)在指定端口創(chuàng)建一個最大隊列長度為maxQueue的服務器套接字。在一個多地址主機上,localAddress指定該套接字約束的IP地址TCP編程模型Java實用編程技術與項目實戰(zhàn)服務器套接字類構造方法TCP編程模型Java實用編程技術與項目實戰(zhàn)服務器端程序實現(xiàn)在端口8080上監(jiān)聽提供服務,從客戶端讀入數(shù)據(jù)后再向客戶端發(fā)送信息客戶端發(fā)送數(shù)據(jù)后再接收服務器數(shù)據(jù)該實例簡單地實現(xiàn)兩者的通信TCP編程模型Java實用編程技術與項目實戰(zhàn)import.*;importjava.io.*;publicclassServer //服務器端程序{publicstaticvoidmain(String[]args){try{ServerSocketss=newServerSocket(8080);//創(chuàng)建ServerSocket對象,端口為8080while(true){Socketsocket=ss.accept(); //接收客戶端請求//監(jiān)聽客戶端的請求,等待連接,連接完成返回socket套接字TCP編程模型Java實用編程技術與項目實戰(zhàn)InputStreamin=socket.getInputStream(); //定義輸入流對象OutputStreamout=socket.getOutputStream(); //定義輸出流對象InputStreamReaderreader=newInputStreamReader(in);BufferedReaderbufReader=newBufferedReader(reader);StringreadLine=bufReader.readLine();//讀入一行System.out.println(readLine);PrintStreamps=newPrintStream(out);ps.print("Hello"); //輸出信息ps.flush();bufReader.close();ps.close();ss.close();}}catch(Exceptione){System.out.println("Error");}}}TCP編程模型Java實用編程技術與項目實戰(zhàn)import.*;importjava.io.*;publicclassClient //客戶端程序{

publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{try{Socketsocket=newSocket("localhost",8080);//在本地機的8080端口創(chuàng)建socket對象DataInputStreamdis=newDataInputStream(newBufferedInputStream(socket.getInputStream())); //準備接收服務器端信息DataOutputStreamdos=newDataOutputStream(newBufferedOutputStream(socket.getOutputStream())); //準備發(fā)送數(shù)據(jù)對象TCP編程模型Java實用編程技術與項目實戰(zhàn)dos.writeUTF("HelloServer!"); //發(fā)送數(shù)據(jù)dos.flush(); System.out.println(dis.readUTF());dis.close();dos.close();socket.close();}catch(Exceptione){System.out.println("Error");}}}TCP編程模型Java實用編程技術與項目實戰(zhàn)對于現(xiàn)在的大多數(shù)網(wǎng)絡需求,TCP/IP型網(wǎng)絡已經(jīng)基本可以滿足其網(wǎng)絡需求了。TCP包含很多在擁擠的網(wǎng)絡中處理擁塞控制的復雜算法以及信息丟失的悲觀的預測。這導致了一個效率很差的傳輸數(shù)據(jù)方式數(shù)據(jù)報(Datagrams)是在機器間傳遞的信息包,一旦數(shù)據(jù)報被釋放給它們預定的目標,不保證它們一定到達目的地,甚至不保證一定存在數(shù)據(jù)的接收者。同樣,數(shù)據(jù)報被接受時,不保證它在傳輸過程不受損壞,不保證發(fā)送它的機器仍在那兒等待響應UDP編程模型Java實用編程技術與項目實戰(zhàn)Java通過兩個類實現(xiàn)UDP協(xié)議頂層的數(shù)據(jù)報DatagramPacket類:創(chuàng)建一個用于發(fā)送的數(shù)據(jù)報,當接收數(shù)據(jù)UDP數(shù)據(jù)報時,可以使用DatagramPacket類讀取數(shù)據(jù)報中的數(shù)據(jù),發(fā)送者和其他消息DatagramSocket類:封裝了套結字的有關信息和操作發(fā)送端,是用來發(fā)送和接受DatagramPackets的機制UDP編程模型Java實用編程技術與項目實戰(zhàn)DatagramSocket類構造方法publicDatagramSocket()throwsExcetpionpublicDatagramSocket(intport)throwsExceptionDatagramSocket()方法創(chuàng)建一個負責發(fā)數(shù)據(jù)報的DatagramSocket類對象,DatagramSocket(intport)創(chuàng)建一個指定了端口號的DatagramSocket類對象。UDP編程模型Java實用編程技術與項目實戰(zhàn)DatagramPackets可以用四個構造方法DatagramPacket(bytedata[],intsize)DatagramPacket(bytedata[],intoffset,intsize)DatagramPacket(bytedata[],intsize,InetAddressipAddress,intport)DatagramPacket(bytedata[],intoffset,intsize,InetAddressipAddress,intport)UDP編程模型Java實用編程技術與項目實戰(zhàn)

DatagramPacket方法UDP編程模型方法含義InetAddressgetAddress()返回目標文件InetAddress,一般用于發(fā)送IntgetPort()返回端口號byte[]getData()返回包含在數(shù)據(jù)包中的字節(jié)數(shù)組數(shù)據(jù)。多用

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論