文章詳情頁
用Java實(shí)現(xiàn)多線程服務(wù)器程序
瀏覽:84日期:2024-06-28 11:44:16
內(nèi)容: 摘要:在Java出現(xiàn)之前,編寫多線程程序是一件煩瑣且伴隨許多不安全因素的事情。利用Java,編寫安全高效的多線程程序變得簡單,而且利用多線程和Java的網(wǎng)絡(luò)包我們可以方便的實(shí)現(xiàn)多線程服務(wù)器程序。 ---- Java是伴隨Internet的大潮產(chǎn)生的,對(duì)網(wǎng)絡(luò)及多線程具有內(nèi)在的支持,具有網(wǎng)絡(luò)時(shí)代編程語言的一切特點(diǎn)。從Java的當(dāng)前應(yīng)用看,Java主要用于在Internet或局域網(wǎng)上的網(wǎng)絡(luò)編程,而且將Java作為主流的網(wǎng)絡(luò)編程語言的趨勢愈來愈明顯。實(shí)際工作中,我們除了使用商品化的服務(wù)器軟件外,時(shí)常需要按照實(shí)際環(huán)境編寫自己的服務(wù)器軟件,以完成特定任務(wù)或與特定客戶端軟件實(shí)現(xiàn)交互。在實(shí)現(xiàn)服務(wù)器程序時(shí),為提高程序運(yùn)行效率,降低用戶等待時(shí)間,我們應(yīng)用了在Java Applet中常見的多線程技術(shù)。 ---- 一、Java中的服務(wù)器程序與多線程 ---- 在Java之前,沒有一種主流編程語言能夠提供對(duì)高級(jí)網(wǎng)絡(luò)編程的固有支持。在其他語言環(huán)境中,實(shí)現(xiàn)網(wǎng)絡(luò)程序往往需要深入依賴于操作平臺(tái)的網(wǎng)絡(luò)API的技術(shù)中去,而Java提供了對(duì)網(wǎng)絡(luò)支持的無平臺(tái)相關(guān)性的完整軟件包,使程序員沒有必要為系統(tǒng)網(wǎng)絡(luò)支持的細(xì)節(jié)而煩惱。 ---- Java軟件包內(nèi)在支持的網(wǎng)絡(luò)協(xié)議為TCP/IP,也是當(dāng)今最流行的廣域網(wǎng)/局域網(wǎng)協(xié)議。Java有關(guān)網(wǎng)絡(luò)的類及接口定義在java.net包中。客戶端軟件通常使用java.net包中的核心類Socket與服務(wù)器的某個(gè)端口建立連接,而服務(wù)器程序不同于客戶機(jī),它需要初始化一個(gè)端口進(jìn)行監(jiān)聽,遇到連接呼叫,才與相應(yīng)的客戶機(jī)建立連接。Java.net包的ServerSocket類包含了編寫服務(wù)器系統(tǒng)所需的一切。下面給出ServerSocket類的部分定義。 public class ServerSocket { public ServerSocket(int port) throws IOException ; public Socket accept() throws IOException ; public InetAddress getInetAddress() ; public int getLocalPort() ; public void close() throws IOException ; public synchronized void setSoTimeout (int timeout) throws SocketException ; public synchronized int getSoTimeout() throws IOException ; } ---- ServerSocket構(gòu)造器是服務(wù)器程序運(yùn)行的基礎(chǔ),它將參數(shù)port指定的端口初始化作為該服務(wù)器的端口,監(jiān)聽客戶機(jī)連接請(qǐng)求。Port的范圍是0到65536,但0到1023是標(biāo)準(zhǔn)Internet協(xié)議保留端口,而且在Unix主機(jī)上,這些端口只有root用戶可以使用。一般自定義的端口號(hào)在8000到16000之間。僅初始化了ServerSocket還是遠(yuǎn)遠(yuǎn)不夠的,它沒有同客戶機(jī)交互的套接字(Socket),因此需要調(diào)用該類的accept方法接受客戶呼叫。Accept()方法直到有連接請(qǐng)求才返回通信套接字(Socket)的實(shí)例。通過這個(gè)實(shí)例的輸入、輸出流,服務(wù)器可以接收用戶指令,并將相應(yīng)結(jié)果回應(yīng)客戶機(jī)。ServerSocket類的getInetAddress和getLocalPort方法可得到該服務(wù)器的IP地址和端口。setSoTimeout和getSoTimeout方法分別是設(shè)置和得到服務(wù)器超時(shí)設(shè)置,如果服務(wù)器在timout設(shè)定時(shí)間內(nèi)還未得到accept方法返回的套接字實(shí)例,則拋出IOException的異常。 ---- Java的多線程可謂是Java編程的精華之一,運(yùn)用得當(dāng)可以極大地改善程序的響應(yīng)時(shí)間,提高程序的并行性。在服務(wù)器程序中,由于往往要接收不同客戶機(jī)的同時(shí)請(qǐng)求或命令,因此可以對(duì)每個(gè)客戶機(jī)的請(qǐng)求生成一個(gè)命令處理線程,同時(shí)對(duì)各用戶的指令作出反應(yīng)。在一些較復(fù)雜的系統(tǒng)中,我們還可以為每個(gè)數(shù)據(jù)庫查詢指令生成單獨(dú)的線程,并行對(duì)數(shù)據(jù)庫進(jìn)行操作。實(shí)踐證明,采用多線程設(shè)計(jì)可以很好的改善系統(tǒng)的響應(yīng),并保證用戶指令執(zhí)行的獨(dú)立性。由于Java本身是'線程安全'的,因此有一條編程原則是能夠獨(dú)立在一個(gè)線程中完成的操作就應(yīng)該開辟一個(gè)新的線程。 ---- Java中實(shí)現(xiàn)線程的方式有兩種,一是生成Thread類的子類,并定義該子類自己的run方法,線程的操作在方法run中實(shí)現(xiàn)。但我們定義的類一般是其他類的子類,而Java又不允許多重繼承,因此第二種實(shí)現(xiàn)線程的方法是實(shí)現(xiàn)Runnable接口。通過覆蓋Runnable接口中的run方法實(shí)現(xiàn)該線程的功能。本文例子采用第一種方法實(shí)現(xiàn)線程。 ---- 二、多線程服務(wù)器程序舉例 ---- 以下是我們在項(xiàng)目中采用的多線程服務(wù)器程序的架構(gòu),可以在此基礎(chǔ)上對(duì)命令進(jìn)行擴(kuò)充。本例未涉及數(shù)據(jù)庫。如果在線程運(yùn)行中需要根據(jù)用戶指令對(duì)數(shù)據(jù)庫進(jìn)行更新操作,則應(yīng)注意線程間的同步問題,使同一更新方法一次只能由一個(gè)線程調(diào)用。這里我們有兩個(gè)類,receiveServer包含啟動(dòng)代碼(main()),并初始化ServerSocket的實(shí)例,在accept方法返回用戶請(qǐng)求后,將返回的套接字(Socket)交給生成的線程類serverThread的實(shí)例,直到該用戶結(jié)束連接。 //類receiveServer import java.io.*; import java.util.*; import java.net.*; public class receiveServer{ final int RECEIVE_PORT=9090; //該服務(wù)器的端口號(hào) //receiveServer的構(gòu)造器 public receiveServer() { ServerSocket rServer=null; //ServerSocket的實(shí)例 Socket request=null; //用戶請(qǐng)求的套接字 Thread receiveThread=null; try{ rServer=new ServerSocket(RECEIVE_PORT); //初始化ServerSocket System.out.println('Welcome to the server!'); System.out.println(new Date()); System.out.println('The server is ready!'); System.out.println('Port: '+RECEIVE_PORT); while(true){ //等待用戶請(qǐng)求 request=rServer.accept(); //接收客戶機(jī)連接請(qǐng)求 receiveThread=new serverThread(request); //生成serverThread的實(shí)例 receiveThread.start(); //啟動(dòng)serverThread線程 } }catch(IOException e){ System.out.println(e.getMessage());} } public static void main(String args[]){ new receiveServer(); } //end of main } //end of class //類serverThread import java.io.*; import java.net.*; class serverThread extends Thread { Socket clientRequest; //用戶連接的通信套接字 BufferedReader input; //輸入流 PrintWriter output; //輸出流 public serverThread(Socket s) { //serverThread的構(gòu)造器 this.clientRequest=s; //接收receiveServer傳來的套接字 InputStreamReader reader; OutputStreamWriter writer; try{ //初始化輸入、輸出流 reader=new InputStreamReader (clientRequest.getInputStream()); writer=new OutputStreamWriter (clientRequest.getOutputStream()); input=new BufferedReader(reader); output=new PrintWriter(writer,true); }catch(IOException e){ System.out.println(e.getMessage());} output.println('Welcome to the server!'); //客戶機(jī)連接歡迎詞 output.println('Now is: '+new java.util.Date()+' '+ 'Port:'+clientRequest.getLocalPort()); output.println('What can I do for you?'); } public void run(){ //線程的執(zhí)行方法 String command=null; //用戶指令 String str=null; boolean done=false; while(!done){ try{ str=input.readLine(); //接收客戶機(jī)指令 }catch(IOException e){ System.out.println(e.getMessage());} command=str.trim().toUpperCase(); if(str==null || command.equals('QUIT')) //命令quit結(jié)束本次連接 done=true; else if(command.equals('HELP')){ //命令help查詢本服務(wù)器可接受的命令 output.println('query'); output.println('quit'); output.println('help'); } else if(command.startsWith('QUERY')) { //命令query output.println('OK to query something!'); } //else if …….. //在此可加入服務(wù)器的其他指令 else if(!command.startsWith('HELP') && !command.startsWith('QUIT') && !command.startsWith('QUERY')){ output.println('Command not Found! Please refer to the HELP!'); } }//end of while try{ clientRequest.close(); //關(guān)閉套接字 }catch(IOException e){ System.out.println(e.getMessage()); } command=null; }//end of run ---- 啟動(dòng)該服務(wù)器程序后,可用telnet machine port命令連接,其中machine為本機(jī)名或地址,port為程序中指定的端口。也可以編寫特定的客戶機(jī)軟件通過TCP的Socket套接字建立連接。 摘自《計(jì)算機(jī)世界日?qǐng)?bào)》 Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標(biāo)簽:
Java
相關(guān)文章:
1. jsp實(shí)現(xiàn)登錄驗(yàn)證的過濾器2. SpringBoot+TestNG單元測試的實(shí)現(xiàn)3. jsp文件下載功能實(shí)現(xiàn)代碼4. Android實(shí)現(xiàn)側(cè)滑菜單DrawerLayout5. FP-Growth算法的Java實(shí)現(xiàn)+具體實(shí)現(xiàn)思路+代碼6. python實(shí)現(xiàn)監(jiān)聽鍵盤7. VUE和Antv G6實(shí)現(xiàn)在線拓?fù)鋱D編輯操作8. 在Vue中使用CSS3實(shí)現(xiàn)內(nèi)容無縫滾動(dòng)的示例代碼9. JSP實(shí)現(xiàn)帶查詢條件的通用分頁組件10. PHPMailer發(fā)送郵件功能實(shí)現(xiàn)流程
排行榜
