Java語言程序設計-教案56學時-第12、13章 Java多線程機制;Java網絡編程_第1頁
Java語言程序設計-教案56學時-第12、13章 Java多線程機制;Java網絡編程_第2頁
Java語言程序設計-教案56學時-第12、13章 Java多線程機制;Java網絡編程_第3頁
Java語言程序設計-教案56學時-第12、13章 Java多線程機制;Java網絡編程_第4頁
Java語言程序設計-教案56學時-第12、13章 Java多線程機制;Java網絡編程_第5頁
已閱讀5頁,還剩21頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

PAGEPAGE15授課內容學時分配教學方法與手段進度計劃(周次)課堂講授(學時)上機實踐(學時)Java語言入門標識符、關鍵字和數據類型運算符、表達式和語句6421~2類與對象141042~5子類與繼承6425-7接口與實現4227-8內部類與異常類2208常用實用類6429-10組件及事件處理64210-11輸入、輸出流22012JDBC與MySQL數據庫42212-13Java多線程機制22013Java網絡的基本知識22014總結22014總學時=SUM(ABOVE)56=SUM(ABOVE)40=SUM(ABOVE)16

各章教學實施計劃章節(jié)題目第12章Java多線程機制12.1節(jié)-12.3節(jié),12.5節(jié)-12.6節(jié)12.4節(jié),12.7-12.12節(jié)(課時所限,學生自主學習)學時2教學目的、要求(分了解、理解、掌握三個層次):1、了解Java中的線程。2、掌握Thread類與線程的創(chuàng)建。3、掌握線程的常用方法。4、掌握線程同步。5、了解協調同步的線程、線程聯合。6、掌握GUI線程。7、了解計時器線程、守護線程。教學內容(包括基本內容、重點、難點):基本內容:Java中的線程◆Thread類與線程的創(chuàng)建線程的常用方法◆線程同步協調同步的線程線程聯合GUI線程計時器線程重點是多線程的概念;如何創(chuàng)建多線程;線程同步;GUI線程。難點是理解多線程機制、wait()方法、notify()方法。討論、思考題、作業(yè):習題121(1)-(9)2(1)-(3)3(1)-(8)4(1)-(3)預習第13章參考及補充內容:1、學習操作系統(tǒng)的基本知識,了解操作系統(tǒng)中如何管理CUP資源的。2、結合例題7,討論如何實現線程同步及其必要性。

課堂教學實施計劃第19課教學過程設計:復習分鐘;授新課95分鐘討論5分鐘;其它分鐘授課類型(請打√):理論課√討論課□實驗課□習題課□其它□教學方式(請打√):講授√討論□示教□指導□其它□教學手段(請打√):多媒體模型□實物□掛圖□音像□其它√主要內容基本內容:Java中的線程◆Thread類與線程的創(chuàng)建線程的常用方法◆線程同步協調同步的線程線程聯合GUI線程計時器線程重點是多線程的概念;如何創(chuàng)建多線程;線程同步;GUI線程。難點是理解多線程機制、wait()方法、notify()方法。第12章Java多線程機制§12.1進程與線程§12.1.1操作系統(tǒng)與進程程序是一段靜態(tài)的代碼,它是應用軟件執(zhí)行的藍本。進程是程序的一次動態(tài)執(zhí)行過程,它對應了從代碼加載、執(zhí)行至執(zhí)行完畢的一個完整過程,這個過程也是進程本身從產生、發(fā)展至消亡的過程?,F代操作系統(tǒng)可以同時管理一個計算機系統(tǒng)中的多個進程,即可以讓計算機系統(tǒng)中的多個進程輪流使用CPU資源?!?2.1.2進程與線程線程是比進程更小的執(zhí)行單位,一個進程在其執(zhí)行過程中,可以產生多個線程,形成多條執(zhí)行線索,每條線索,即每個線程也有它自身的產生、存在和消亡的過程。線程間可以共享進程中的某些內存單元(包括代碼與數據),線程的中斷與恢復可以更加節(jié)省系統(tǒng)的開銷?!?2.2Java中的線程§12.2.1Java的多線程機制Java語言的一大特性點就是內置對多線程的支持。Java虛擬機快速地把控制從一個線程切換到另一個線程。這些線程將被輪流執(zhí)行,使得每個線程都有機會使用CPU資源?!?2.2.2主線程(main線程)每個Java應用程序都有一個缺省的主線程。當JVM(JavaVirtualMachine虛擬機)加載代碼,發(fā)現main方法之后,就會啟動一個線程,這個線程稱為“主線程”(main線程),該線程負責執(zhí)行main方法。JVM一直要等到Java應用程序中的所有線程都結束之后,才結束Java應用程序?!?2.2.3線程的狀態(tài)與生命周期建的線程在它的一個完整的生命周期中通常要經歷如下的四種狀態(tài):新建:當一個Thread類或其子類的對象被聲明并創(chuàng)建時,新生的線程對象處于新建狀態(tài)。運行:線程必須調用start()方法(從父類繼承的方法)通知JVM,這樣JVM就會知道又有一個新一個線程排隊等候切換了。一旦輪到它來享用CPU資源時,此線程的就可以脫離創(chuàng)建它的主線程獨立開始自己的生命周期了。中斷:有4種原因的中斷:JVM將CPU資源從當前線程切換給其他線程,使本線程讓出CPU的使用權處于中斷狀態(tài)。線程使用CPU資源期間,執(zhí)行了sleep(intmillsecond)方法,使當前線程進入休眠狀。線程使用CPU資源期間,執(zhí)行了wait()方法。線程使用CPU資源期間,執(zhí)行某個操作進入阻塞狀態(tài)。死亡:處于死亡狀態(tài)的線程不具有繼續(xù)運行的能力。線程釋放了實體。例子1Example12_1.javapublicclassExample12_1{publicstaticvoidmain(Stringargs[]){ //主線程負責執(zhí)行main方法SpeakElephantspeakElephant;SpeakCarspeakCar;speakElephant=newSpeakElephant(); //創(chuàng)建線程speakCar=newSpeakCar(); //創(chuàng)建線程speakElephant.start(); //啟動線程speakCar.start(); //啟動線程for(inti=1;i<=15;i++){System.out.print("主人"+i+"");}}}SpeakElephant.javapublicclassSpeakElephantextendsThread{//Thread類的子類publicvoidrun(){for(inti=1;i<=20;i++){System.out.print("大象"+i+"");}}}SpeakCar.javapublicclassSpeakCarextendsThread{//Thread類的子類publicvoidrun(){for(inti=1;i<=20;i++){System.out.print("轎車"+i+"");}}}§12.2.4線程調度與優(yōu)先級處于就緒狀態(tài)的線程首先進入就緒隊列排隊等候CPU資源,同一時刻在就緒隊列中的線程可能有多個。Java虛擬機(JVM)中的線程調度器負責管理線程,調度器把線程的優(yōu)先級分為10個級別,分別用Thread類中的類常量表示。Java調度器的任務是使高優(yōu)先級的線程能始終運行,一旦時間片有空閑,則使具有同等優(yōu)先級的線程以輪流的方式順序使用時間片?!?2.3Thread類與線程的創(chuàng)建§12.3.1使用Thread的子類在Java語言中,用Thread類或子類創(chuàng)建線程對象。在編寫Thread類的子類時,需要重寫父類的run()方法,其目的是規(guī)定線程的具體操作,否則線程就什么也不做,因為父類的run()方法中沒有任何操作語句?!?2.3.2使用Thread類創(chuàng)建線程的另一個途徑就是用Thread類直接創(chuàng)建線程對象。使用Thread創(chuàng)建線程通常使用的構造方法是:Thread(Runnabletarget)該構造方法中的參數是一個Runnable類型的接口。在創(chuàng)建線程對象時必須向構造方法的參數傳遞一個實現Runnable接口類的實例,該實例對象稱作所創(chuàng)線程的目標對象,當線程調用start()方法后,一旦輪到它來享用CPU資源,目標對象就會自動調用接口中的run()方法(接口回調)。例子2Example12_2.javapublicclassExample12_2{publicstaticvoidmain(Stringargs[]){ThreadspeakElephant; //用Thread聲明線程ThreadspeakCar; //用Thread聲明線程ElephantTargetelephant; //elephant是目標對象CarTargetcar; //car是目標對象elephant=newElephantTarget(); //創(chuàng)建目標對象car=newCarTarget(); //創(chuàng)建目標對象speakElephant=newThread(elephant); //創(chuàng)建線程,其目標對象是elephantspeakCar=newThread(car); //創(chuàng)建線程,其目標對象是carspeakElephant.start(); //啟動線程speakCar.start(); //啟動線程for(inti=1;i<=15;i++){System.out.print("主人"+i+"");}}}ElephantTarget.javapublicclassElephantTargetimplementsRunnable{ //實現Runnable接口publicvoidrun(){for(inti=1;i<=20;i++){System.out.print("大象"+i+"");}}}CarTarget.javapublicclassCarTargetimplementsRunnable{ //實現Runnable接口publicvoidrun(){for(inti=1;i<=20;i++){System.out.print("轎車"+i+"");}}}§12.3.2使用Thread類例題線程間可以共享相同的內存單元(包括代碼與數據),并利用這些共享單元來實現數據交換、實時通信與必要的同步操作。例子3(Example12_3.java,House.java)中使用Thread類創(chuàng)建兩個模擬貓和狗的線程,貓和狗共享房屋中的一桶水,即房屋是線程的目標對象,房屋中的一桶水被貓和狗共享。貓和狗輪流喝水(狗喝的多,貓喝的少),當水被喝盡時,貓和狗進入死亡狀態(tài)。貓或狗在輪流喝水的過程中,主動休息片刻(讓Thread類調用sleep(intn)進入中斷狀態(tài)),而不是等到被強制中斷喝水。例子3Example12_3.javapublicclassExample12_3{publicstaticvoidmain(Stringargs[]){Househouse=newHouse();house.setWater(10);Threaddog,cat;dog=newThread(house); //dog和cat的目標對象相同cat=newThread(house); //cat和dog的目標對象相同dog.setName("狗");cat.setName("貓");dog.start();cat.start();}}House.javapublicclassHouseimplementsRunnable{intwaterAmount; //用int變量模擬水量publicvoidsetWater(intw){waterAmount=w;}publicvoidrun(){while(true){Stringname=Thread.currentThread().getName();if(name.equals("狗")){System.out.println(name+"喝水");waterAmount=waterAmount-2; //狗喝的多}elseif(name.equals("貓")){System.out.println(name+"喝水");waterAmount=waterAmount-1; //貓喝的少}System.out.println("剩"+waterAmount);try{Thread.sleep(2000); //間隔時間}catch(InterruptedExceptione){}if(waterAmount<=0){return;}}}}§12.3.3目標對象與線程的關系從對象和對象之間的關系角度上看,目標對象和線程的關系有以下兩種情景。目標對象和線程完全解耦目標對象沒有組合線程對象.目標對象經常需要通過獲得線程的名字(因為無法獲得線程對象的引用)以便確定是哪個線程正在占用CPU資源,即被JVM正在執(zhí)行的線程。目標對象組合線程(弱耦合)目標對象可以組合線程.目標對象類組合線程對象時,目標對象可以通過獲得線程對象的引用.例子4Example12_4.javapublicclassExample12_4{publicstaticvoidmain(Stringargs[]){Househouse=newHouse();house.setWater(10);house.dog.start();house.cat.start();}}House.javapublicclassHouseimplementsRunnable{intwaterAmount; //用int變量模擬水量Threaddog,cat; //線程是目標對象的成員House(){dog=newThread(this); //當前House對象作為線程的目標對象cat=newThread(this);}publicvoidsetWater(intw){waterAmount=w;}publicvoidrun(){while(true){Threadt=Thread.currentThread();if(t==dog){System.out.println("家狗喝水");waterAmount=waterAmount-2; //狗喝的多}elseif(t==cat){System.out.println("家貓喝水");waterAmount=waterAmount-1; //貓喝的少}System.out.println("剩"+waterAmount);try{Thread.sleep(2000); //間隔時間}catch(InterruptedExceptione){}if(waterAmount<=0){return;}}}}§12.3.4關于run()方法啟動的次數對于具有相同目標對象的線程,當其中一個線程享用CPU資源時,目標對象自動調用接口中的run方法,這時,run方法中的局部變量被分配內存空間,當輪到另一個線程享用CPU資源時,目標對象會再次調用接口中的run方法,那么,run()方法中的局部變量會再次分配內存空間。也就是說run()方法已經啟動運行了兩次,分別運行在不同的線程中,即運行在不同的時間片內?!?2.4線程的常用方法(因課時少的原因,這一節(jié)簡要介紹,學生可以自主學習)start():線程調用該方法將啟動線程,使之從新建狀態(tài)進入就緒隊列排隊,一旦輪到它來享用CPU資源時,就可以脫離創(chuàng)建它的線程獨立開始自己的生命周期了。run():Thread類的run()方法與Runnable接口中的run()方法的功能和作用相同,都用來定義線程對象被調度之后所執(zhí)行的操作,都是系統(tǒng)自動調用而用戶程序不得引用的方法。sleep(intmillsecond):優(yōu)先級高的線程可以在它的run()方法中調用sleep方法來使自己放棄CPU資源,休眠一段時間。isAlive():線程處于“新建”狀態(tài)時,線程調用isAlive()方法返回false。在線程的run()方法結束之前,即沒有進入死亡狀態(tài)之前,線程調用isAlive()方法返回true。currentThread():該方法是Thread類中的類方法,可以用類名調用,該方法返回當前正在使用CPU資源的線程。interrupt():一個占有CPU資源的線程可以讓休眠的線程調用interrupt()方法“吵醒”自己,即導致休眠的線程發(fā)生InterruptedException異常,從而結束休眠,重新排隊等待CPU資源。例子5Example12_5.javapublicclassExample12_5{publicstaticvoidmain(Stringargs[]){Homehome=newHome();ThreadshowTime=newThread(home);showTime.start();}}Home.javaimportjava.util.Date;importjava.text.SimpleDateFormat;publicclassHomeimplementsRunnable{inttime=0;SimpleDateFormatm=newSimpleDateFormat("hh:mm:ss");Datedate;publicvoidrun(){while(true){date=newDate();System.out.println(m.format(date));time++;try{Thread.sleep(1000);}catch(InterruptedExceptione){}if(time==3){Threadthread=Thread.currentThread();thread=newThread(this);thread.start();}}}}例子6Example12_6.javapublicclassExample12_6{publicstaticvoidmain(Stringargs[]){ClassRoomroom6501=newClassRoom();room6501.student.start();room6501.teacher.start();}}ClassRoom.javapublicclassClassRoomimplementsRunnable{Threadstudent,teacher;//教室里有student和teacher兩個線程ClassRoom(){teacher=newThread(this);student=newThread(this);teacher.setName("王教授");student.setName("張三");}publicvoidrun(){if(Thread.currentThread()==student){try{System.out.println(student.getName()+"正在睡覺,不聽課");Thread.sleep(1000*60*60);}catch(InterruptedExceptione){System.out.println(student.getName()+"被老師叫醒了");}System.out.println(student.getName()+"開始聽課");}elseif(Thread.currentThread()==teacher){for(inti=1;i<=3;i++){System.out.println("上課!");try{Thread.sleep(500);}catch(InterruptedExceptione){}}errupt();//吵醒student}}}§12.5線程同步(重點)在處理多線程問題時,我們必須注意這樣一個問題:當兩個或多個線程同時訪問同一個變量,并且一個線程需要修改這個變量。我們應對這樣的問題作出處理。在處理線程同步時,要做的第一件事就是要把修改數據的方法用關鍵字synchronized來修飾。所謂線程同步就是若干個線程都需要使用一個synchronized修飾的方法。例子7(Example12_7.java,Bank.java)中有兩個線程:會計和出納,他倆共同擁有一個帳本.程序要保證其中一人使用saveOrTake(intamount)時,另一個人將必須等待,即saveOrTake(intamount)方法應當是一個synchronized方法。例子7Example12_7.javapublicclassExample12_7{publicstaticvoidmain(Stringargs[]){Bankbank=newBank();bank.setMoney(200);Threadaccountant,//會計cashier;//出納accountant=newThread(bank);cashier=newThread(bank);accountant.setName("會計");cashier.setName("出納");accountant.start();cashier.start();}}Bank.javapublicclassBankimplementsRunnable{intmoney=200;publicvoidsetMoney(intn){money=n;}publicvoidrun(){if(Thread.currentThread().getName().equals("會計"))saveOrTake(300);elseif(Thread.currentThread().getName().equals("出納"))saveOrTake(150);}publicsynchronizedvoidsaveOrTake(intamount){//存取方法if(Thread.currentThread().getName().equals("會計")){for(inti=1;i<=3;i++){money=money+amount/3; //每存入amount/3,稍歇一下System.out.println(Thread.currentThread().getName()+"try{Thread.sleep(1000); //這時出納仍不能使用saveOrTake方法}catch(InterruptedExceptione){}}}elseif(Thread.currentThread().getName().equals("出納")){for(inti=1;i<=3;i++){ //出納使用存取方法取出150money=money-amount/3; //每取出amount/3,稍歇一下System.out.println(Thread.currentThread().getName()+try{Thread.sleep(1000); //這時會計仍不能使用saveOrTake方法}catch(InterruptedExceptione){}}}}}§12.6協調同步的線程(重點)wait()方法可以中斷方法的執(zhí)行,使本線程等待,暫時讓出CPU的使用權,并允許其它線程使用這個同步方法。notifyAll()方法通知所有的由于使用這個同步方法而處于等待的線程結束等待。曾中斷的線程就會從剛才的中斷處繼續(xù)執(zhí)行這個同步方法,并遵循“先中斷先繼續(xù)”的原則。notify()方法只是通知處于等待中的線程的某一個結束等待。例子8Example12_8.javapublicclassExample12_8{publicstaticvoidmain(Stringargs[]){TicketHouseofficer=newTicketHouse();Threadzhangfei,likui;zhangfei=newThread(officer);zhangfei.setName("張飛");likui=newThread(officer);likui.setName("李逵");zhangfei.start();likui.start();}}TicketHouse.javapublicclassTicketHouseimplementsRunnable{intfiveAmount=2,tenAmount=0,twentyAmount=0;publicvoidrun(){if(Thread.currentThread().getName().equals("張飛")){saleTicket(20);}elseif(Thread.currentThread().getName().equals("李逵")){saleTicket(5);}}privatesynchronizedvoidsaleTicket(intmoney){if(money==5){//如果使用該方法的線程傳遞的參數是5,就不用等待fiveAmount=fiveAmount+1;System.out.println("給"+Thread.currentThread().getName()+"入場 券,"+Thread.currentThread().getName()+"的錢正好");}elseif(money==20){while(fiveAmount<3){try{System.out.println("\n"+Thread.currentThread().getName()

+"靠邊等...");wait();//如果使用該方法的線程傳遞的參數是20須等待System.out.println("\n"+Thread.currentThread().getName()

+"繼續(xù)買票");}catch(InterruptedExceptione){}}fiveAmount=fiveAmount-3;twentyAmount=twentyAmount+1;券Thread.currentThread().getName()+"給20,找贖15元");}notifyAll();}}§12.7線程聯合--§12.11應用舉例按56學時的計劃安排,這部分內容由學生自主學習。在前面的基礎上,基本可以完成??偨Y線程是比進程更小的執(zhí)行單位。一個進程在其執(zhí)行過程中,可以產生多個線程。Java虛擬機(JVM)中的線程調度器負責管理線程,在采用時間片的系統(tǒng)中,每個線程都有機會獲得CUP的使用權。理解線程的創(chuàng)建的兩種方法。線程同步是指幾個線程都需要調用同一個同步方法(用synchronized修飾的方法)。學會使用wait()方法和notifyAll()方法。作業(yè)習題121(1)-(9)2(1)-(3)3(1)-(8)4(1)-(3)預習第13章本章課結束授課內容學時分配教學方法與手段進度計劃(周次)課堂講授(學時)上機實踐(學時)Java語言入門標識符、關鍵字和數據類型運算符、表達式和語句6421~2類與對象141042~5子類與繼承6425-7接口與實現4227-8內部類與異常類2208常用實用類6429-10組件及事件處理64210-11輸入、輸出流22012JDBC與MySQL數據庫42212-13Java多線程機制22013Java網絡的基本知識22014總結22014總學時=SUM(ABOVE)56=SUM(ABOVE)40=SUM(ABOVE)16

各章教學實施計劃章節(jié)題目第13章Java網絡編程13.1節(jié)-13.3節(jié)13.4節(jié)-13.8節(jié)(課時所限,學生自主學習)學時2教學目的、要求(分了解、理解、掌握三個層次):1、了解URL類、InetAdress類。2、掌握套接字。3、了解UDP數據報、廣播數據報及Java遠程調用(RMI)。教學內容(包括基本內容、重點、難點):基本內容:URL類InetAdress類套接字UDP數據報廣播數據報Java遠程調用(RMI)重點URL對象,InetAddress類中主要方法的使用,套接字。難點理解套接字連接。討論、思考題、作業(yè):習題131(1)-(5)2(1)-(3)參考及補充內容:1、學習計算機網絡、Internet的基本知識,了解常用的網絡協議。2、結合例題3,討論套接字連接的機制及注意事項。

課堂教學實施計劃第20課教學過程設計:復習分鐘;授新課95分鐘討論5分鐘;其它分鐘授課類型(請打√):理論課√討論課□實驗課□習題課□其它□教學方式(請打√):講授√討論□示教□指導□其它□教學手段(請打√):多媒體模型□實物□掛圖□音像□其它√主要內容基本內容:URL類InetAdress類套接字UDP數據報廣播數據報Java遠程調用(RMI)重點URL對象,InetAddress類中主要方法的使用,套接字。難點理解套接字連接。第13章Java網絡編程§13.1URL類URL類是包中的一個重要的類,URL的實例封裝著一個統(tǒng)一資源定位符(UniformResourceLocator),使用URL創(chuàng)建對象的應用程序稱作客戶端程序。一個URL對象通常包含最基本的三部分信息:協議、地址、資源?!?3.1.1URL的構造方法URL類通常使用如下的構造方法創(chuàng)建一個URL對象:publicURL(Stringspec)throwsMalformedURLExceptionpublicURL(Stringprotocol,Stringhost,Stringfile)throwsMalformedURLException§13.1.2讀取URL中的資源URL對象調用InputStreamopenStream()方法可以返回一個輸入流,該輸入流指向URL對象所包含的資源。通過該輸入流可以將服務器上的資源讀入到客戶端。例子1Example13_1.javaimport.*;importjava.io.*;importjava.util.*;publicclassExample13_1{publicstaticvoidmain(Stringargs[]){Scannerscanner;URLurl;ThreadreadURL;//負責讀取資源的線程Looklook=newLook();//線程的目標對象System.out.println("輸入URL資源,例如:");scanner=newScanner(System.in);Stringsource=scanner.nextLine();try{url=newURL(source);look.setURL(url);readURL=newThread(look);readURL.start();}catch(Exceptionexp){System.out.println(exp);}}}Look.javaimport.*;importjava.io.*;publicclassLookimplementsRunnable{URLurl;publicvoidsetURL(URLurl){this.url=url;}publicvoidrun(){try{InputStreamin=url.openStream();byte[]b=newbyte[1024];intn=-1;while((n=in.read(b))!=-1){Stringstr=newString(b,0,n);System.out.print(str);}}catch(IOExceptionexp){}}}§13.2InetAdress類§13.2.1地址的表示Internet上的主機有兩種方式表示地址:域名例如IP地址例如10包中的InetAddress類對象含有一個Internet主機地址的域名和IP地址,例如/0?!?3.2.2獲取地址獲取Internet上主機的地址可以使用InetAddress類的靜態(tài)方法getByName(Strings);獲得一個InetAddress對象,該對象含有主機地址的域名和IP地址,該對象用如下格式表示它包含的信息:/0獲取本地機的地址我們可以使用InetAddress類的靜態(tài)方法getLocalHost()獲得一個InetAddress對象,該對象含有本地機的域名和IP地址。例子2Example13_2.javaimport.*;publicclassExample13_2{publicstaticvoidmain(Stringargs[]){try{InetAddressaddress_1=InetAddress.getByName("www.sina.

");System.out.println(address_1.toString());InetAddressaddress_2=InetAddress.getByName("");System.out.println(address_2.toString());}catch(UnknownHostExceptione){System.out.println("無法找到");}}}§13.3套接字(重點)§13.3.1套接字IP地址標識Internet上的計算機,端口號標識正在計算機上運行的進程(程序)。端口號被規(guī)定為一個16位的0~65535之間的整數。當兩個程序需要通信時,它們可以通過使用Socket類建立套接字對象并連接在一起(端口號與IP地址的組合得出一個網絡套接字)?!?3.3.2客戶端套接字客戶端的程序使用Socket類建立負責連接到服務器的套接字對象。建立連接到服務器的套接字對象:try{Socketmysocket=newSocket(“8”,1880);}catch(IOExceptione){}與mysocket相關的方法getInputStream()獲得一個輸入流getOutputStream()獲得一個輸出流用getInputStream()得到的輸入流接到另一個DataInputStream數據流上用getOutputStream()得到的輸出流接到另一個DataOutputStream數據流上§13.3.3ServerSocket對象與服務器端套接字服務器必須建立一個ServerSocket對象,該對象通過將客戶端的套接字對象和服務器端的一個套接字對象連接起來,從而達到連接的目的。建立ServerSocket對象:try{ServerSocketserverForClient=newServerSocket(2010);}catch(IOExceptione){}使用方法accept()將客戶的套接字和服務器端的套接字連接起來,代碼如下所示:try{Socketsc=serverForClient.accept();}catch(IOExceptione){}所謂“接收”客戶的套接字連接就是accept()方法會返回一個和客戶端Socket對象相連接的Socket對象??蛻舳说奶捉幼肢@得的輸入\輸出流和服務器端的套接字獲得的輸出\輸入流互相連接.例子31.客戶端Client.javaimportjava.io.*;import.*;publicclassClient{publicstaticvoidmain(Stringargs[]){String[]mess={"2010世界杯在哪舉行?","巴西進入世界杯了嗎?","中國進入世界 杯了嗎?"};Socketmysocket;DataInputStreamin=null;DataOutputStreamout=null;try{mysocket=newSocket("",2010);in=newDataInputStream(mysocket.getInputStream());out=newDataOutputStream(mysocket.getOutputStream());for(inti=0;i<mess.length;i++){out.writeUTF(mess[i]);Strings=in.readUTF();//in讀取信息,阻塞狀態(tài)System.out.println("客戶收到服務器的回答:"+s);Thread.sleep(500);}}catch(Exceptione){System.out.println("服務器已斷開"+e);}}}2.服務器端Server.javaimportjava.io.*;import.*;publicclassServer{publicstaticvoidmain(Stringargs[]){String[]answer={"南非","進入世界杯了","哈哈……問題真逗!"};ServerSocketserverForClient=null;SocketsocketOnServer=null;DataOutputStreamout=null;DataInputStreamin=null;try{serverForClient=newServerSocket(2010);}catch(IOExceptione1){System.out.println(e1);}try{System.out.println("等待客戶呼叫");out=newDataOutputStream(socketOnServer.getOutputStream());in=newDataInputStream(socketOnServer.getInputStream());for(inti=0;i<answer.length;i++){Strings=in.readUTF();//in讀取信息,阻塞狀態(tài)System.out.println("服務器收到客戶的提問:"+s);out.writeUTF(answer[i]);Thread.sleep(500);}}catch(Exceptione){System.out.println("客戶已斷開"+e);}}}§13.3.4使用多線程技術為了防止堵塞線程,服務器端收到一個客戶的套接字后,就應該啟動一個專門為該客戶服務的線程。在下面的例子4中,客戶使用Socket類不帶參數的構造方法Socket()創(chuàng)建一個套接字對象,該對象需調用publicvoidconnect(SocketAddressendpoint)throwsIOException請求和參數SocketAddress指定地址的套接字建立連接。為了使用connect方法,可以使用SocketAddress的子類InetSocketAddress創(chuàng)建一個對象,InetSocketAddress的構造方法是:InetSocketAddress(InetAddressaddr,intport)例子41.客戶端Client.javaimportjava.io.*;import.*;importjava.util.*;publicclassClient{publicstaticvoidmain(Stringargs[]){Scannerscanner=newScanner(System.in);Socketmysocket=null;DataInputStreamin=null;DataOutputStreamout=null;ThreadreadData;Readread=null;try{mysocket=newSocket();read=newRead();readData=newThread(read); //負責讀取信息的線程System.out.print("輸入服務器的IP:");StringIP=scanner.nextLine();System.out.print("輸入端口號:");intport=scanner.nextInt();if(mysocket.isConnected()){}else{InetAddressaddress=InetAddress.getByName(IP);InetSocketAddresssocketAddress=newInetSocketAddress

(address,port);mysocket.connect(socketAddress);in=newDataInputStream(mysocket.getInputStream());out=newDataOutputStream(mysocket.getOutputStream());read.setDataInputStream(in);readData.start(); //啟動負責讀取信息的線程}}catch(Exceptione){System.out.println("服務器已斷開"+e);}System.out.print("輸入圓的半徑(放棄請輸入N):");while(scanner.hasNext()){doubleradius=0;try{rad

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論