<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    OMG,到底在尋找什么..................
    (構造一個完美的J2EE系統所需要的完整知識體系)
    posts - 198,  comments - 37,  trackbacks - 0
    原貼地址http://blog.csdn.net/clearwater21cn/category/99145.aspx

    QuickServer開發指南(1)- 介紹?

    QuickServer是一個免費的開源Java庫,用于快速創建健壯的多線程、多客戶端TCP服務器應用程序。使用QuickServer,用戶可以只集中處理應用程序的邏輯/協議,從而方便的建立功能強大的服務器應用。該程序由Akshathkumar Shetty設計和實現。
    ??? QuickServer安裝目錄下的example中有演示其功能的例子,最新的例子和文檔可以通過網站 http://www.quickserver.orghttp://quickserver.sourceforge.net獲得。
    ??? 該指南適用于所有想要學習和使用QuickServer的人,閱讀該指南應具備基本的Java編程知識,基本的網絡和sockets方面的知識也會有所幫助

    1.?為什么需要QuickServer?
    ??? 無論何種編程語言,socket編程對程序員來說都不是一件容易的事,創建多線程、多客戶端的服務器socket更像一場惡夢了。在每個新的軟件中處理多socket連接,我們都要浪費大把時間編寫大量重復的代碼。QuickServer因而誕生——使用Java創建多線程、多客戶端服務器應用。

    2.?基本構造
    QuickServer在應用邏輯上為開發者提供了四個類
    o?ClientCommandHandler
    ??? 處理與客戶端的交互——使用字符串命令
    o?ClientObjectHandler [可選類]
    ??? 處理與客戶端的交互——使用對象命令
    o?Authenticator [可選類]
    ??? 客戶端驗證
    o?ClientData [可選類]
    ??? 客戶端數據載體(支持類)
    下面的圖表顯示了QuickServer庫的基本構造。QuickServer模塊上七個輻條表示七個方法:
    o?java.lang.String info()
    o?int getServiceState()
    o?boolean initService(java.lang.Object[] config)
    o?boolean startService()
    o?boolean resumeService()
    o?boolean suspendService()
    o?boolean stopService()


    ??? 與QuickServer模塊相連接的四個組件中只有ClientCommandHandler是必須的。
    ??? QuickServerConfig對象由initService()方法構建。它實現了QuickServer,在讀取XML配置后,QuickServerConfig用于QuickServer配置。
    ??? ClientHandler線程對象用于客戶端緩沖池。可選的ClientData類與ClientHandler類關聯,ClientHandler對象容器參考ClientCommandHandler,ClientObjectHandler(可選),Authenticator(可選)對象包含在QuickServer主函數中。
    ??? 注意:上圖中并未顯示QSAdminServer,它是圖中QuickServer的組成部分。

    3.?主要特點
    o?創建多線程、多客戶端TCP服務器應用程序
    o?支持安全服務的創建:SSL, TLS
    o?清楚的分離服務、協議、驗證邏輯
    o?GUI圖形界面遠程管理支持
    o?Command Shell對服務器的本地管理
    o?無須斷開客戶端連接的重啟或延遲服務
    o?為線程的再利用和大多數的使用對象建立緩沖池
    o?完全的日志支持(Java構建)
    o?支持發送和接收字符串、字節、二進制、序列化Java對象
    o?在同樣的xml中支持能夠存貯指定應用數據的XML配置
    o?支持通過IP地址限制服務
    o?支持基于XML的JDBC映射
    o?支持服務配置模式
    o?支持從xml加載/重新加載用于jar包
    o?在QuickServer中添加處理hooks
    o?指定允許的最大客戶端連接數
    o?在通常的TCP連接上支持談判安全連接
    o?支持鑒別和查詢客戶端
    o?附帶典型例子——FTPServer, CmdServer,EchoWebServer, ChatServer

    4.?1.4版的新功能
    o?為QuickServer添加安全模式:SSL, TLS
    o?添加SecureManagerLoader管理安全模式
    o?在通常的TCP連接上添加談判安全連接
    o?添加初始化服務hooks
    o?為通信添加二進制模式
    o?為QsAdminServer通信添加QSAdminAPI
    o?為QuickServer 添加findAllClientByKey
    o?添加ConnectionLostException類
    o?改進ClientHandler、安全配置
    o?新例子——XmlAdder:一個簡單的xml服務,可添加兩個整數
    o?新例子——PipeServer:一個簡單的重定向服務

    QuickServer開發指南(2)- 安裝

    1. 運行環境
    QuickServer 1.2以上的版本需要(其實在偶看來一個1.4版以上JDK足矣):
    ? 推薦1.4版以上Java虛擬機,最低1.3版(未經測試).
    ? Java Logging API(下列之一)
    o java.util.logging包 [JDK 1.4版自帶]
    o Lumberjack庫 [http://javalogging.sourceforge.net/]
    ? XML 解析器 (下列之一)
    o SAX (面向XML 2.0的API) [JDK 1.4版自帶]
    o JAXP (面向XML解析的Java API) 1.1 [JDK 1.4版自帶]
    o Xerces [http://xml.apache.org/xerces2-j]
    o Crimson [http://xml.apache.org/crimson]
    ? Jakarta公共組件{Digester, Pool}
    o 這些產品包含在Apache開發的軟件中(http://www.apache.org/)。Jar包都在以下的庫中:BeanUtils, Collections, Logging. [http://jakarta.apache.org/commons/components.html]. Apache軟件許可證在文件“apache_license.txt”中。

    2. 安裝
    ??? 目前最新的1.4.1版QuickServer可在http://www.quickserver.org/download.html下載。安裝QuickServer,假設安裝路徑為$INSTALL_PATH。
    ??? 在CLASSPATH中添加"$INSTALL_PATH\dist\QuickServer.jar",在PATH中添加"$INSTALL_PATH\bin"。
    ??? 另外測試socket的通訊軟件推薦SockTest,在http://www.ddost.com/soft/sockettest 可下載到最新版本。Windows自帶的telnet也可以進行測試。

    QuickServer開發指南(3)- 構建EchoServer?

    學習怎樣使用QuickServer庫的一個好的方法是學習它提供的例子。在QuickServer安裝路徑下的examples文件夾里有許多典型的例子。
    ??? 下面的章節里我們模仿其中的一個例子EchoServer來構建一個服務器。EchoServer是一個簡單的TCP服務器,主要功能是將用戶發送的字符串加上前綴"Echo :"后返回。雖然這個例子可用性不強,但它是一個對QuickServer所有特點的一個很好的示范。我們從構建一個最基本的服務器開始,以后慢慢給它添加新的功能。

    1.?代碼
    ??? 首先實現EchoServer最基本的功能:將用戶發送的字符串加上前綴"Echo :"后返回。
    ??? 在本地創建一個文件夾存放需要的代碼,如在c:\projects\中建立echoserver文件夾,然后創建一個類EchoServer.java:

    01 package echoserver;

    02

    03 import org.quickserver.net.*;

    04 import org.quickserver.net.server.*;

    05

    06 import java.io.*;

    07

    08 public class EchoServer {

    09 public static void main(String s[]) {

    10 QuickServer myServer =

    11 new QuickServer("echoserver.EchoCommandHandler");

    12 myServer.setPort(4123);

    13 myServer.setName("EchoServer v 1.0");

    14 try {

    15 myServer.startServer();

    16 } catch(AppException e){

    17 System.err.println("Error in server : "+e);

    18 }

    19 }

    20 }


    ??? 在第10行和第11行定義了一個QuickServer對象myServer,通過一個String對象"echoserver.EchoCommandHandler"聲明了要加載的類,這個類面向所有客戶端做命令處理器,實現了org.quickserver.net.server.ClientCommandHandler接口,我們即將創建。
    ??? 第12行設置了一個服務器端口用來做監聽,然后設置整個應用的名字(第13行)。最后啟動服務(第15行)。

    ??? 接下來為EchoServer創建一個實現org.quickserver.net.server.ClientCommandHandler接口的類EchoCommandHandler.java,用來處理服務器發送的命令。

    01 // EchoCommandHandler.java

    02 package echoserver;

    03

    04 import java.net.*;

    05 import java.io.*;

    06 import org.quickserver.net.server.ClientCommandHandler;

    07 import org.quickserver.net.server.ClientHandler;

    08

    09 public class EchoCommandHandler implements ClientCommandHandler {

    10

    11 public void gotConnected(ClientHandler handler)

    12 throws SocketTimeoutException, IOException {

    13 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

    14 handler.sendClientMsg("| Welcome to EchoServer v 1.3 |");

    15 handler.sendClientMsg("| Send 'Quit' to exit |");

    16 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

    17 }

    18 public void lostConnection(ClientHandler handler)

    19 throws IOException {

    20 handler.sendSystemMsg("Connection lost : " +

    21 handler.getSocket().getInetAddress());

    22 }

    23 public void closingConnection(ClientHandler handler)

    24 throws IOException {

    25 handler.sendSystemMsg("Closing connection : " +

    26 handler.getSocket().getInetAddress());

    27 }

    28

    29 public void handleCommand(ClientHandler handler, String command)

    30 throws SocketTimeoutException, IOException {

    31 if(command.equals("Quit")) {

    32 handler.sendClientMsg("Bye ;-)");

    33 handler.closeConnection();

    34 } else {

    35 handler.sendClientMsg("Echo : "+command);

    36 }

    37 }

    38 }


    ??? 根據QuickServer的要求,這個類必須實現ClientCommandHandler接口。
    ??? 當客戶端建立一個連接(11行),gotConnected()方法被調用。在這個方法里面,我們給客戶端發送歡迎文本(13-16行),這些文本使用通過ClientHandler的sendClientMsg()方法發送給客戶端。我們也會使用ClientHandler的sendSystemMessage()方法顯示客戶端連接的InetAddress(20-21,25-26行)。
    ??? handlerCommand()方法是ClientCommandHandler接口的核心方法,因為服務器接收客戶端發送的任何命令時都要調用該方法。在我們對這個方法的實現中,我們會檢查命令是否為"Quit"(31行),如果是,我們將發送一些提示文本表示服務器即將關閉連接,然后關閉連接(33行)。否則,將命令加上前綴"Echo :"返回給用戶。

    2.?運行和測試
    o?運行命令提示符程序(cmd.exe)
    o?進入代碼所在文件夾根目錄,如c:\projects
    o?編譯代碼? javac echoserver\*.java
    o?若無編譯錯誤,運行服務器:
    ??? set classpath=%classpath%;d:\QuickServer\dist\QuickServer.jar;.\(類所在文件夾)
    ??? java echoserver.EchoServer
    o?您將會看到如下信息:

    o?測試我們的服務器是否可以正常工作。再運行一個cmd程序,進入SocketTest.jar所在目錄,鍵入java -jar sockettest.jar命令,彈出一個窗口。在IP Address中輸入"127.0.0.1",在Port里輸入"4123",點擊"Connect"按鈕,將看到窗口中顯示如下圖的信息。


    ??? 若使用telnet,可鍵入命令:open localhost 4123
    ??? 在Message中輸入一些字符串,點擊"Send"按鈕,瀏覽器將會返回一個加了前綴"Echo :"的字符串。發送"Quit",服務器斷開連接。

    QuickServer開發指南(4)- 添加認證

    現在我們給剛剛創建的服務器添加認證功能。
    ??? 查看org.quickserver.net.server.QuickServer的文檔(docs文件夾下)你可以注意到里面有一個方法
    ??? public void setAuthenticator(java.lang.String authenticator)
    ??? 閱讀文檔可知此方法中的authenticator字符串是實現org.quickserver.net.server.Authenticator接口的方法的全名。
    ??? Authenticator接口有兩個實現:
    ??? org.quickserver.net.server.QuickAuthenticator:這個類用來驗證連接QuickServer的客戶端。它只用一個實例處理所有的QuickServer驗證。(推薦)
    ??? org.quickserver.net.server.ServerAuthenticator:這個類同樣用來驗證連接QuickServer的客戶端,但對每一個驗證的處理都會創建一個實例。
    ??? 接下來給EchoServer加驗證功能。簡單點,客戶端輸入的用戶名和密碼一致就算驗證通過。
    ??? 首先,在同樣的文件夾里創建一個驗證類:EchoServerQuickAuthenticator

    01 package echoserver;

    02

    03 import org.quickserver.net.server.*;

    04 import java.io.*;

    05

    06 public class EchoServerQuickAuthenticator extends QuickAuthenticator {

    07

    08 public boolean askAuthorisation(ClientHandler clientHandler)

    09 throws IOException {

    10 String username = askStringInput(clientHandler, "User Name :");

    11 String password = askStringInput(clientHandler, "Password :");

    12

    13 if(username==null || password ==null)

    14 return false;

    15

    16 if(username.equals(password)) {

    17 sendString(clientHandler, "Auth OK");

    18 return true;

    19 } else {

    20 sendString(clientHandler, "Auth Failed");

    21 return false;

    22 }

    23 }

    24 }

    ??? 這個類擴展了org.quickserver.net.server.QuickAuthenticator(第6行),在askAuthorisation()方法中(8行),通過askStringInput()方法要求客戶端輸入用戶名和密碼,并讀入客戶端輸入的信息(10-11行)。這個方法繼承自QuickAuthenticator。如果用戶名與密碼相等,發送正確信息并返回"true"(16-18行),否則發送錯誤信息并返回"false"(20-21行)。

    ??? 接下來我們要告訴QuickServer使用我們新創建的驗證類來做驗證器。修改前一章創建的EchoServer.java文件,代碼如下(粗體為修改的代碼):

    01 package echoserver;

    02

    03 import com.ddost.net.*;

    04 import com.ddost.net.server.*;

    05

    06 import java.io.*;

    07

    08 public class EchoServer {

    09

    10 public static void main(String s[]) {

    11

    12 QuickServer myServer =

    13 new QuickServer("echoserver.EchoCommandHandler");

    14myServer.setAuthenticator(

    15"echoserver.EchoServerQuickAuthenticator");

    16 myServer.setPort(4123);

    17 myServer.setName("EchoServer v 1.0");

    18try {

    19 myServer.startServer();

    20 } catch(AppException e){

    21 System.err.println("Error in server : "+e);

    22 }

    23 }

    24 }


    ??? OK,將修改好的文件編譯,按照前一章講述的方法運行程序。這次當我們點擊"Connect"時,瀏覽器會要求我們輸入用戶名和密碼。如果輸入的用戶名和密碼一致就可以登錄。如果輸入錯誤五次以上,瀏覽器會提示"-ERR Max Auth Try Reached"并自動斷開連接。這個次數和提示信息可以通過QuickServer類的setMaxAuthTry() 和 setMaxAuthTryMsg()修改。


    ??? 有時在驗證過程中我們可能需要中途退出而不是等待驗證結束,這時輸入"Quit"是不起作用的。我們可以這樣修改代碼,有兩個方法:
    ??? 一是從EchoServerQuickAuthenticator類中的askAuthorisation()方法拋出一個org.quickserver.net.AppException異常,代碼如下:
    ??? String username = askStringInput(clientHandler, "User Name :");
    ??? if (username != null &&
    ??????? username.equalsIgnoreCase("QUIT")) {
    ????? sendString(clientHandler, "Logged out.");
    ????? throw new AppException("Quit");
    }
    ??? 或者參考ClientHandler,關閉連接,代碼如下:
    ??? String username = askStringInput(clientHandler, "User Name :");
    ??? if (username != null &&
    ??????? username.equalsIgnoreCase("QUIT")) {
    ????? sendString(clientHandler, "Logged out.");
    ????? clientHandler.closeConnection();
    ????? return false;
    }
    ??? ClientHandler對象能夠提供很多客戶端連接的有用信息,如IP地址。更多信息請參考API文檔。

    注意:
    ??? o 不要在驗證器類中存貯任何客戶端相關信息,如果需要,必須存放在ClientData類中--下一章將講解該部分內容。
    ??? o 必須確認askAuthorisation()方法是線程安全的。

    QuickServer開發指南(5)- 客戶數據

    既然不能在ClientCommandHandler和ServerAuthenticator類中保存客戶數據,我們使用ClientData類的handleCommand()或askAuthorisation()方法來存儲所有的客戶端信息。
    ??? 示范一下這個特點有什么用。還是以EchoServer為例,當用戶發送"Hello"時,我們給他一個問候。如果用戶再發送"Hello",我們提醒他已經發了n次"Hello"。接下來定義ClientData類來存儲用戶名以及他向服務器發送"Hello"的次數。

    1.?代碼
    1.?在EchoServer中創建一個EchoServerData類

    01 //---- EchoServerData.java ----

    02?package echoserver;

    03

    04 import org.quickserver.net.server.*;

    05 import java.io.*;

    06

    07 public class EchoServerData implements ClientData {

    08 private int helloCount;

    09 private String username;

    10

    11 public void setHelloCount(int count) {

    12 helloCount = count;

    13 }

    14 public int getHelloCount() {

    15 return helloCount;

    16 }

    17

    18 public void setUsername(String username) {

    19 this.username = username;

    20 }

    21 public String getUsername() {

    22 return username;

    23 }

    24 }

    25 //--- end of code ---


    2.?告訴QuickServer用這個EchoServerData來做為它的ClientData類。
    ??? 修改前面創建的EchoServer.java,代碼如下:

    01 package echoserver;

    02

    03 import org.quickserver.net.*;

    04 import org.quickserver.net.server.*;

    05

    06 import java.io.*;

    07

    08 public class EchoServer {

    09 public static void main(String s[]) {

    10

    11 String cmd = "echoserver.EchoCommandHandler";

    12 String auth = "echoserver.EchoServerQuickAuthenticator";

    13 String data = "echoserver.EchoServerData";

    14

    15 QuickServer myServer = new QuickServer(cmd);

    16 myServer.setAuthenticator(auth);

    17 myServer.setClientData(data);

    18

    19 myServer.setPort(4123);

    20 myServer.setName("Echo Server v 1.0");

    21 try {

    22 myServer.startServer();

    23 } catch(AppException e){

    24 System.out.println("Error in server : "+e);

    25 }

    26 }

    27 }


    ??? 上面的代碼中,我們將配置信息寫入String對象來設置QuickServer。???

    3.?修改Authenticator類,也就是EchoServerAuthenticator類,讓它在ClientData對象中存儲用戶名。下面是修改后的代碼:

    01 package echoserver;

    02

    03 import org.quickserver.net.server.*;

    04 import java.io.*;

    05

    06 public class EchoServerQuickAuthenticator extends QuickAuthenticator {

    07

    08 public boolean askAuthorisation(ClientHandler clientHandler)

    09 throws IOException {

    10 String username = askStringInput(clientHandler, "User Name :");

    11 if(username!=null && username.equalsIgnoreCase("QUIT")) {

    12 sendString(clientHandler, "Logged out.");

    13 //close the connection

    14 clientHandler.closeConnection();

    15 return false;

    16 }

    17

    18 String password = askStringInput(clientHandler, "Password :");

    19

    20 if(username==null || password ==null)

    21 return false;

    22

    23 if(username.equals(password)) {

    24 sendString(clientHandler, "Auth OK");

    25 //store the username in ClientData

    26 EchoServerData data = (EchoServerData)clientHandler.getClientData();

    27 data.setUsername(username);

    28 return true;

    29 } else {

    30 sendString(clientHandler, "Auth Failed");

    31 return false;

    32 }

    33 }

    34 }

    4.?修改ClientCommandHandler實現類EchoCommandHandler。如果用戶發送"Hello",給他一個問候。如果他發送多次"Hello",告訴他已經發送了n次"Hello"。下面是修改后的代碼:

    01 // EchoCommandHandler.java

    02 package echoserver;

    03

    04 import java.net.*;

    05 import java.io.*;

    06 import org.quickserver.net.server.ClientCommandHandler;

    07 import org.quickserver.net.server.ClientHandler;

    08

    09 public class EchoCommandHandler implements ClientCommandHandler {

    10

    11 public void gotConnected(ClientHandler handler)

    12 throws SocketTimeoutException, IOException {

    13 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

    14 handler.sendClientMsg("| Welcome to EchoServer v 1.0 |");

    15 handler.sendClientMsg("| Note: Password = Username |");

    16 handler.sendClientMsg("| Send 'Quit' to exit |");

    17 handler.sendClientMsg("+++++++++++++++++++++++++++++++");

    18 }

    19 public void lostConnection(ClientHandler handler)

    20 throws IOException {

    21 handler.sendSystemMsg("Connection lost : " +

    22 handler.getSocket().getInetAddress());

    23 }

    24 public void closingConnection(ClientHandler handler)

    25 throws IOException {

    26 handler.sendSystemMsg("Closing connection : " +

    27 handler.getSocket().getInetAddress());

    28 }

    29

    30 public void handleCommand(ClientHandler handler, String command)

    31 throws SocketTimeoutException, IOException {

    32 if(command.equals("Quit")) {

    33 handler.sendClientMsg("Bye ;-)");

    34 handler.closeConnection();

    35 } if(command.equalsIgnoreCase("hello")) {

    36 EchoServerData data = (EchoServerData) handler.getClientData();

    37 data.setHelloCount(data.getHelloCount()+1);

    38 if(data.getHelloCount()==1) {

    39 handler.sendClientMsg("Hello "+data.getUsername());

    40 } else {

    41 handler.sendClientMsg("You told Hello "+data.getHelloCount()+

    42 " times. ");

    43 }

    44 } else {

    45 handler.sendClientMsg("Echo : "+command);

    46 }

    47 }

    48 }


    5.?編譯改好的程序,運行,使用SocketTest測試。登錄后,發送"Hello",系統會給一個問候,再次發送"Hello",它將告訴你發送了多少次"Hello"。
    ?
    4.2?創建ClientData池

    ??? 現在我們知道ClientData可以正常工作了。但是對每一個連接QuickServer的客戶端都要創建一個新的ClientData對象,可能會造成性能上的瓶頸,尤其對性能要求較高的服務器來說。
    ??? 我們可以創建一個ClientData池對象,無論客戶端什么時候進行連接,都使用同一個對象。首先實現下面的接口:
    ??? org.quickserver.util.pool.PoolableObject
    ??? 查找QuickServer API文檔可以發現PoolableObject只有兩個必須實現的方法:
    ??? org.apache.commons.pool.PoolableObjectFactory屬于通常的工廠方法。
    ??? isPoolable()判斷對象是否可以成為池對象。

    PoolableObjectFactory
    org.apache.commons.pool.PoolableObjectFactory接口包含了以下方法:
    o?void activateObject(Object obj):重新初始化一個實例。
    o?void destroyObject(Object obj):銷毀一個不再需要的實例。
    o?Object makeObject():創建一個實例。
    o?void passivateObject(Object obj):禁止初始化一個實例。
    o?boolean validateObject(Object obj):確定一個實例是否安全。

    ??? 我們可以擴展一個基于無操作的實現來創建可"池"化的對象:
    ??? org.apache.commons.pool.BasePoolableObjectFactory
    ??? 這個類只有一個抽象方法makeObject()和一個validateObject()方法,它只返回true。
    ??? 我們來創建一個EchoServerPoolableData類。

    01 //---- EchoServerPoolableData.java ----

    02 package echoserver;

    03

    04 import org.quickserver.net.server.*;

    05 import java.io.*;

    06

    07 public class EchoServerPoolableData

    08 extends EchoServerData

    09 implements org.apache.commons.pool.PoolableObjectFactory {

    10

    11 public void activateObject(Object obj) {

    12 }

    13 public void destroyObject(Object obj) {

    14 if(obj==null) return;

    15 passivateObject(obj);

    16 obj = null;

    17 }

    18 public Object makeObject() {

    19 return new EchoServerPoolableData();

    20 }

    21 public void passivateObject(Object obj) {

    22 EchoServerPoolableData pd = (EchoServerPoolableData)obj;

    23 pd.setHelloCount(0);

    24 pd.setUsername(null);

    25 }

    26 public boolean validateObject(Object obj) {

    27 if(obj==null)

    28 return false;

    29 else

    30 return true;

    31 }

    32 }

    33 //--- end of code ---

    ??? 這個類擴展了我們的EchoServerData,然后我們實現了org.apache.commons.pool.BasePoolableObjectFactory,這個實現是簡單的不需要解釋了。
    ??? 現在我們需要告訴QuickServer使用這個類來代替原來的ClientData類。
    ??????? myServer.setClientData("echoserver.EchoServerPoolableData");
    ??? 編譯修改的程序,可能會報如下錯誤:
    ??????? package org.apache.commons.pool does not exist。
    ??? 這是因為編譯器不知道這個類。可以在環境變量中添加D:\QuickServer\dist\commons-pool.jar包,并在運行時
    ??? set classpath=%classpath%;d:\QuickServer\dist\QuickServer.jar; d:\QuickServer\dist\commons-pool.jar;.\(類所在文件夾)即可。

    posted on 2006-12-04 19:45 OMG 閱讀(1129) 評論(0)  編輯  收藏 所屬分類: Soket

    <2006年12月>
    262728293012
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    IT風云人物

    文檔

    朋友

    相冊

    經典網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 成人免费视频网址| 67pao强力打造高清免费| 日本免费福利视频| 亚洲日韩av无码中文| 美女视频黄a视频全免费| 亚洲伊人久久精品| 无限动漫网在线观看免费| 亚洲午夜在线播放| 波多野结衣久久高清免费| 无码亚洲成a人在线观看| 亚洲成AⅤ人影院在线观看| 一级毛片大全免费播放| 亚洲精品无码永久在线观看你懂的| 美女无遮挡拍拍拍免费视频| 亚洲av之男人的天堂网站 | 亚洲成在人线aⅴ免费毛片| 日韩一区二区在线免费观看| 国产精品亚洲精品爽爽| 国产亚洲精午夜久久久久久| 久久青草91免费观看| 亚洲av午夜精品无码专区| 日本人的色道www免费一区| 四虎国产精品成人免费久久 | 国产亚洲欧洲精品| 美女内射毛片在线看免费人动物| 亚洲AV综合色区无码二区爱AV| 卡1卡2卡3卡4卡5免费视频| 国产黄色片免费看| 亚洲明星合成图综合区在线| 色吊丝最新永久免费观看网站 | 2020因为爱你带字幕免费观看全集| 亚洲H在线播放在线观看H| 免费a级毛片大学生免费观看| a级男女仿爱免费视频| 亚洲中文字幕无码av在线| 免费人妻无码不卡中文字幕18禁| 最新国产乱人伦偷精品免费网站| 国产成人精品日本亚洲专一区| 免费国产在线观看老王影院| 日本一道本不卡免费 | 亚洲无av在线中文字幕|