国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Java后臺服務(wù)程序設(shè)計



何千軍, 軟件工程師, 獨立顧問和自由撰稿人

2002 年 10 月 16 日

在很多大型軟件項目中,都有一些極為重要的后臺服務(wù)程序,它們并不處理具體的系統(tǒng)業(yè)務(wù)邏輯,但對整個系統(tǒng)資源和服務(wù)的協(xié)調(diào)管理卻是不可或缺。本文討論如何完整地編寫一個后臺服務(wù)管理程序,并通過一個具體的后臺服務(wù)管理例子來說明這一技術(shù)實現(xiàn)的技巧。

為什么需要后臺服務(wù)程序?

在許多大型軟件項目中,后臺服務(wù)程序都扮演著極為重要的角色。它們無處不在,例如操作系統(tǒng)的內(nèi)核程序處理各種對操作系統(tǒng)的內(nèi)部調(diào)用;數(shù)據(jù)庫系統(tǒng)的核心管理進(jìn)程處理各種對數(shù)據(jù)庫的讀寫操作和進(jìn)程、資源的管理;大型ERP軟件的內(nèi)核管理程序要完成各種應(yīng)用模塊的資源、通訊管理等等。它們使系統(tǒng)的各種服務(wù)、資源與應(yīng)用的表示之間形成了一個松耦合關(guān)系,這樣就極大地增加了軟件系統(tǒng)的穩(wěn)定性和伸縮性。后臺服務(wù)程序也就是相當(dāng)于軟件系統(tǒng)的管理調(diào)度中心,它是軟件系統(tǒng)的中央處理器,是保證應(yīng)用高效運行的內(nèi)核程序。

在不同的軟件系統(tǒng)中,由于軟件的復(fù)雜程度和功能的不同使得各種軟件系統(tǒng)的后臺服務(wù)程序都有存在較大的差異。但是后臺服務(wù)程序還是有很多共同的特點,一個基本的后臺服務(wù)程序大概可以由四個部分構(gòu)成:通用服務(wù)器框架、服務(wù)與監(jiān)聽、服務(wù)控制、服務(wù)器實現(xiàn)。下面我們就使用具體的代碼來實現(xiàn)一個基本的后臺服務(wù)器程序。



回頁首


通用服務(wù)器框架

在開發(fā)后臺服務(wù)程序中,我們首先實現(xiàn)一個通用服務(wù)器框架類,它能在多個端口提供多線程的服務(wù)(由多個Service對象定義),并且能夠在系統(tǒng)運行時動態(tài)地調(diào)用和實例化Service類并加載新的服務(wù)或卸除已加載的服務(wù)。

清單 1顯示了如何編制一個通用服務(wù)器框架類文件。

【清單 1:通用服務(wù)器框架類文件Server.java】import java.util.*;import java.io.*;import java.net.*;public class Server {  protected Map services;  Set connections;              int maxConnections;             int freeConn;  ThreadGroup threadGroup;  private int currentConn;  private PrintWriter log = new PrintWriter(System.out, true);  public boolean connected = false;  public Properties proPort, proNum;    public synchronized void setControlFlag() {      connected = true;  }    public synchronized void removeControlFlag() {      connected = false;  }    public void setProperty(Properties proPort, Properties proNum) {      this.proPort = proPort;      this.proNum = proNum;  }    public Server(int maxConn) {      this.maxConnections = maxConn;      this.freeConn=maxConnections;      this.threadGroup = new ThreadGroup(Server.class.getName());      currentConn = 0;      this.services = new HashMap();      this.connections = new HashSet(maxConnections);  }  public synchronized void addService(Service service,int port, int maxConn) throws IOException {      String servicename = service.getClass().getName();      Integer key = new Integer(port);      if (services.get(key) != null) throw new IllegalArgumentException("端口:" + port + " 已經(jīng)被占用!");      if (getfreeConnections(maxConn)>=0) {          Listener listener = new Listener(this, port, service, maxConn);          services.put(key,listener);          log.println("啟動" +  servicename + "服務(wù)在" + port +"端口上");          listener.start();      } else {          System.err.println("系統(tǒng)并發(fā)連接限制已經(jīng)達(dá)到最大值!");          System.err.println("服務(wù)" + servicename + " 啟動失敗!");      }  }  public synchronized void addService(Service service,int port) throws IOException {      this.addService(service,port,10);  }  public synchronized boolean removeService(int port) {      Integer key = new Integer(port);      int maxConn =10;      final Listener listener = (Listener) services.get(key);      if (listener == null) {            log.println("Service " + " isn‘t started on port " + port);            return false;      }      services.remove(key);      listener.pleaseStop();       freeConn+=listener.maxConn;      log.println("Close " + listener.service + " on port " + port);      return true;  }  public synchronized void displayStatus(PrintWriter out) {      Iterator keys = services.keySet().iterator();      while (keys.hasNext()) {          Integer port = (Integer) keys.next();          Listener listener = (Listener) services.get(port);          out.println("服務(wù)" + listener.service + "運行" + port + "\n");      }      out.println("連接限制為" + maxConnections);      Iterator conns = connections.iterator();      while (conns.hasNext()) {          Socket s = (Socket) conns.next();          int sport = s.getLocalPort();          Listener listen = (Listener) services.get(new Integer(sport));          String servicename = listen.service;          out.println(servicename + "響應(yīng)請求在" + s.getInetAddress().getHostAddress() + "的" + sport + "端口上");      }      out.println("當(dāng)前連接數(shù)為" + currentConn);      out.println("當(dāng)前系統(tǒng)空閑連接數(shù)為" + freeConn);  }  private synchronized int getfreeConnections(int maxConn) {      int num = -1;      if (freeConn >= maxConn) {            freeConn-=maxConn;            num = freeConn;      }      return num;  }  public synchronized int getConnections() {      return currentConn;  }  public synchronized int  addConnections(Socket s) {      connections.add(s);      return currentConn++;  }  public synchronized int  removeConnections(Socket s) {      connections.remove(s);      try {          s.close();      } catch (Exception e) {      	  System.out.println(e.getMessage());      }      return currentConn--;  }  public synchronized int getConnections(int connections) {      int num = 0;      if ((num=freeConn-connections) >= 0) {          freeConn = num;      } else num = -1;      return num;  }  private synchronized int getFreeConn() {      return freeConn;  }}

如上所述可知,服務(wù)器框架類Server主要是通過端口到監(jiān)聽器影射的散列表services來管理服務(wù)對象,Server類的幾個主要方法說明如下:

  • addService方法:此方法能夠在特定的端口上創(chuàng)建新的服務(wù),即在指定端口上運行指定的Service對象。
  • removeService方法:此方法使服務(wù)器停止指定端口上的服務(wù),并不終止連接,僅使服務(wù)器停止接受新的連接。
  • displayStatus方法:此方法用于打印指定流上服務(wù)器的狀態(tài)信息。

服務(wù)與監(jiān)聽

每個服務(wù)都對應(yīng)著一個監(jiān)聽對象,監(jiān)聽指定端口的連接并在獲得連接請求時調(diào)用addConnection( Socket s, Service service )方法來取得(釋放)一個連接。清單 2顯示了如何編制一個監(jiān)聽類文件。

【清單 2:Listener.java的一個簡單實現(xiàn)】import java.util.*;import java.io.*;import java.net.*;public class Listener extends Thread {  private ServerSocket listener;  private int port;  String service;  Set connections;  private Service runService;  private boolean stop_flag = false;  int maxConn;  private PrintWriter log = new PrintWriter(System.err, true);  private ThreadGroup group;  private int currentConnections = 0;  Server server;  Socket client = null;  public Listener(Server server, int port, Service service, int maxConn, boolean bl) throws IOException {      this.server = server;      this.port = port;      this.service = service.getClass().getName();      this.maxConn = maxConn;      this.group = server.threadGroup;      this.connections = server.connections;      listener = new ServerSocket(this.port);      if (bl == false) listener.setSoTimeout(600000);                this.runService = service;      if (!stop_flag) {          for (int i=0;i<this.maxConn;i++) {                  ConnectionHandler currentThread = new ConnectionHandler(server,logStream);                  new Thread(this.group, currentThread, this.service+this.port+i).start();      	          this.logStream.realLog("向線程組" + group.toString() + "添加一個線程" + this.service+this.port+i);          }      } else throw new IllegalArgumentException("系統(tǒng)并發(fā)連接限制已經(jīng)超過最大值!!");  }  public Listener(Server server, int port, Service service, int maxConn) throws IOException {      this(server, port, service, maxConn, false);  }  public void pleaseStop() {      this.stop_flag = true;      try {          listener.close();      } catch (Exception e) {      }      this.interrupt();  }  public void run() {      while(!stop_flag) {          try {                client = listener.accept();                addConnection(client,runService);          } catch (Exception e) {}      }      try {          client.close();      } catch (IOException e) {}  }  private synchronized void addConnection(Socket s, Service service) {      ConnectionHandler.requestToHandler(s, service);  }}                                               

在實際處理過程中,Listener對象通過在指定端口上與指定服務(wù)的綁定實現(xiàn)監(jiān)聽過程,主要的幾個方法說明如下:

  • pleaseStop:以禮貌的方法停止接受連接。
  • addConnection:把指定要處理的服務(wù)放到線程池中,以等待空閑的線程處理服務(wù)。

監(jiān)聽對象通過傳遞一個Service對象并喚醒它的serve()方法才真正提供了服務(wù)。下面我們就來實現(xiàn)一個具體的服務(wù):

  • 服務(wù)接口Service只有一個抽象方法serve(InputStream in, OutputStream out),它所有服務(wù)實現(xiàn)所必須重寫的一個方法,Listing 3顯示了一個Service接口的定義。
     【清單 3:定義一個Service接口】import java.io.*;import java.net.*;public interface Service {  public void serve(InputStream in, OutputStream out) throws IOException;}

  • 編寫一個簡單的顯示時間服務(wù)類:見清單4。
    【清單 4:一個顯示系統(tǒng)當(dāng)前時間的服務(wù)類Timer.java】import java.util.*;import java.text.*;import java.io.*;import java.net.*;public class Timer implements Service {  public Timer() {  }  public void serve(InputStream in, OutputStream out) throws IOException {      String timeFormat = "yyyy-MM-dd hh:mm:ss";      SimpleDateFormat timeFormatter = new SimpleDateFormat(timeFormat);      BufferedReader from_client = new BufferedReader(new InputStreamReader(in));      PrintWriter outPrint = new PrintWriter(out);      String sDate = timeFormatter.format(new Date());      outPrint.println("當(dāng)前時間是:" + sDate);      outPrint.flush();      try {      	from_client.close();      	outPrint.close();      }catch (Exception e){}  }}

通過實現(xiàn)Service接口可以編寫很多的服務(wù)實現(xiàn)提供各種不同的服務(wù),讀者有興趣也可自己編寫一個服務(wù)來測試一下。



回頁首


服務(wù)控制

服務(wù)控制是在服務(wù)器運行時動態(tài)地操作控制服務(wù)器,如系統(tǒng)運行時,動態(tài)地裝載(卸載)服務(wù),顯示服務(wù)器的狀態(tài)信息等等。為了簡化基本后臺服務(wù)系統(tǒng)的復(fù)雜程度,我們采用創(chuàng)建一個ControlService服務(wù)實例來在運行時管理服務(wù)器。ControlService實現(xiàn)了基于命令的協(xié)議,可用密碼保護操縱服務(wù)器,代碼如清單 5所示:

 【清單 5:服務(wù)控制類文件ControlService.java】import java.io.*;import java.util.*;import java.net.*;import dvb.kuanshi.kssms.util.*;import dvb.kuanshi.kssms.server.Server;public class ControlService implements Service {  Server server;  String password;  public ControlService(Server server, String password) {      this.server = server;      this.password = password;  }  public void serve(InputStream in, OutputStream out) throws IOException {      boolean authorized = false;      BufferedReader from_client = new BufferedReader(new InputStreamReader(in));      PrintWriter to_console = new PrintWriter(System.out, true);      to_console.println("后臺管理服務(wù)響應(yīng)請求!\n");      PrintWriter to_client = new PrintWriter(out);      synchronized (this) {          if(server.connected) {              to_client.println("已經(jīng)有用戶連接,本服務(wù)僅允許一個連接!\n");              to_client.close();              return;          } else server.setControlFlag();      }              to_client.println("Remote Console>");      to_client.flush();            String line;      while ((line=from_client.readLine())!=null) {            int len = line.indexOf("Remote Console>");            line = line.substring(len+1,line.length());            String printStr;            try {            StringTokenizer st = new StringTokenizer(line);            int count = st.countTokens();            if (!st.hasMoreElements()) continue;            String first = st.nextToken().toLowerCase();            if (first.equals("password")) {                String pwd = st.nextToken();                if (pwd.equals(this.password)) {                    to_client.println("OK");                    authorized = true;                } else to_client.println("密碼無效,請重試!\n");            } else if (first.equals("add")) {                if(!authorized) to_client.println("請登陸!\n");                else {                    count--;                    String servicename;                    int Port;                    boolean flag = true;                    if (count>0) {                    	servicename = st.nextToken();                    	Port = Integer.parseInt(st.nextToken());                    	server.addService(loadClass(servicename1), Port);                    	to_client.println("服務(wù)" + servicename + "已經(jīng)加載\n");                    	flag = false;            			                    }                    if (flag) to_client.println("系統(tǒng)不能啟動非法服務(wù):" + servicename);                    else {to_client.println("請輸入服務(wù)名!\n");}                 }            } else if (first.equals("remove")) {                if(!authorized) to_client.println("請登陸!\n");                else {                    count--;                    if (count>0) {                    	int port = Integer.parseInt(st.nextToken());                    	boolean bl = server.removeService(port);                    	if (bl) to_client.println("端口: " + port +"上的服務(wù)已經(jīng)卸載\n");                    	else to_client.println("端口: "+ port +"上無任何服務(wù)運行,卸載操作失??!\n");                    } else to_client.println("請輸入端口名!\n");                }            } else if(first.equals("status")) {                if(!authorized) to_client.println("請登陸!\n");                else server.displayStatus(to_client);            } else if(first.equals("help")) {                if(!authorized) to_client.println("請登陸!\n");                else printHelp(to_client);            } else if(first.equals("quit")) break;            else to_client.println("命令不能識別!\n");            } catch(Exception e) {to_client.println("系統(tǒng)后臺出錯" + e.getMessage() +"\n");            printHelp(to_client);            }            to_client.println("Remote Console>");                    to_client.flush();        }        to_client.flush();        authorized = false;        server.removeControlFlag();        to_client.close();        from_client.close();  }  private void printHelp(PrintWriter out) {        out.println("COMMANDS:" +                                  "\tpassword <password>\n" +                                  "\t\tadd <servicename> <port>\n" +                                  "\t\tremove <port>\n" +                                  "\t\tstatus\n" +                                  "\t\thelp\n" +                                  "\t\tquit\n");  }  protected Service loadClass(String servicename) {      Service s = null;      try {          Class serviceClass = Class.forName(servicename);          s = (Service) serviceClass.newInstance();      } catch (Exception e) {      }      return s;  }}

服務(wù)器實現(xiàn)和運行
服務(wù)器實現(xiàn)主要完成服務(wù)器的初始化,啟動服務(wù)控制實例等工作,代碼如清單 6所示:

 【清單 6:runServer.java的一個簡單實現(xiàn)】import java.util.*;public class runServer {  public runServer() {  }  public static void main(String[] args) {      try {          int argLen = args.length;          System.out.println("正在初始化系統(tǒng)請等待......");          System.out.println("");          int maxConn = 30;                    Server server = new Server(maxConn);                    System.out.println("################################################################");	  System.out.println("#                                                              #");	  System.out.println("#                     后臺服務(wù)管理系統(tǒng)                      #");	  System.out.println("#                                                              #");	  System.out.println("################################################################");	  System.out.println();          if (argLen>2) {          for (int i = 0;i<argLen;i++) {              if (args[i].equals("-s")) {                  i++;                  String password = args[i];                  i++;                  int port = Integer.parseInt(args[i]);                  server.addService(new ControlService(server,password), port, 2);              } else {                  String servicename = args[i];                  i++;                  int port = Integer.parseInt(args[i]);                  server.addService(loadClass(servicename), port);              }          }          } else throw new IllegalArgumentException("參數(shù)數(shù)目不正確!");          System.out.println("系統(tǒng)啟動,進(jìn)入監(jiān)聽服務(wù)模式......");      } catch (Exception e) {          throw new IllegalArgumentException(e.getMessage());      }   }  protected static Service loadClass(String servicename) {      Service s = null;      try {          Class serviceClass = Class.forName(servicename);          s = (Service) serviceClass.newInstance();      } catch (Exception e) {      }      return s;  }}

下面我們就可以啟動示例程序來測試一下了。

如清單 7所示,以密碼保護方式(密碼為test)啟動后臺服務(wù),在6809啟動服務(wù)控制實例,在6810端口啟動。

 【清單 7:啟動后臺服務(wù)程序】 % java runServer -s test 6809 Timer 6810

在另外一個窗口,執(zhí)行如下命令,將顯示當(dāng)前系統(tǒng)的時間。

 % java clientConnect 6810

在另外一個窗口,執(zhí)行如下命令,你將能查看系統(tǒng)服務(wù)狀態(tài)信息,并動態(tài)地裝載你寫的服務(wù)對象,你可以測試一下。

  % java clientConnect 6809

現(xiàn)在,一個基本的后臺服務(wù)程序即編制完成了。實際上,一個大型軟件的后臺服務(wù)程序是非常復(fù)雜的,上面的例子希望能起到拋磚引玉的效果。要寫出性能良好的后臺服務(wù)程序還有很多工作要做。



回頁首


參考資料

  • 要了解更多的 Java信息,請閱讀 java.sun.com的 主頁

  • 下載后臺服務(wù)程序示例全部代碼: code.zip


回頁首


關(guān)于作者

何千軍,軟件工程師,獨立顧問和自由撰稿人。參加了多項大型軟件系統(tǒng)設(shè)計,主要從事分布式Internet系統(tǒng)的開發(fā)??梢酝ㄟ^ heqianjun@163.net 和我聯(lián)系。





本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
淺出Java Socket 編程
一篇不錯的介紹Java Socket編程的文章3 — IT技術(shù)
服務(wù)器端應(yīng)用程序
java socket 實現(xiàn)服務(wù)端與客戶端
Java RMI 框架(遠(yuǎn)程方法調(diào)用)
簡單聊天程序java socket
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服