0

私は2日目からこのコードに苦しんでいます。実際、私はサーバー側とクライアント側を持つアプリケーションを開発しています。サーバーはクライアントから毎秒リクエストを受信し、データベースに接続してリクエストを処理してから、結果をクライアントに送り返します。クライアントがサーバーの前に起動した場合、指定されたポートと指定されたホストでサーバーに接続しようとし続けるようにします。
1.これはサーバー側です。

try
    {   
        Client client = new Client(jTable1,jLabel3);
        Thread t = new Thread(client);
        t.start();

    }catch(IOException e){}

クラスClient.java

public class Client implements Runnable{

private int svrPort = 0;
ServerSocket serverConnect = null;
static  Socket clientSocket = null;
static  ClientConnectThread t[] = new ClientConnectThread[1000];
JTable jtable;
JLabel jlabel;

public Client(JTable table, JLabel label) throws IOException {

    this.svrPort = 9450;
    this.jtable = table;
    this.jlabel = label;

}

public void run(){
    try{
        serverConnect = new ServerSocket(this.svrPort);

    }catch(IOException e){}
    while(true){
        try{
            clientSocket = serverConnect.accept ();
            for(int i=0; i<=1000; i++){ //I can accept up to 1000 clients
        if(t[i]==null)
        {
            (t[i] = new ClientThread(client, t, jtable, jlabel)).start();
                        System.out.println ("Etat12. Apres bloc try");
            break;
        }
    }
        }catch(IOException e){}
    }
}

}

クラスClientThread.java

public ClientThread(Socket socket, ClientThread t[], JTable table, JLabel label){

    this._socket = socket;
    this.jTable = table;
    this.jlabel = label;
    this.totalConnected = 0;       
    this.t = t;
}

public void run(){

    int index = 0;
    try{
        this._output = new PrintWriter(this._socket.getOutputStream ());
        this._input = new BufferedReader(new InputStreamReader(this._socket.getInputStream()));

        while((clientMsg = this._input.readLine ()) != null){
            if(clientMsg.equals ("@CONNECT")){ // If it is the first time the user is signig in, fill the table

                jTable.setValueAt (this._socket.getInetAddress (), index, 0);
                jTable.setValueAt (new Date(), index, 1);
                jTable.setValueAt (new Date(), index, 2);
                totalConnected++;
                jlabel.setText ("");
                jlabel.setText (totalConnected+"");

            }else if(Integer.parseInt (clientMsg) == 1){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByType (1).size () == 0){
                    }
                    _output.println (this.getData.getDataByPeriod (1));
                }else{System.out.println("You are not connected to the database server");}

            }else if(Integer.parseInt (clientMsg) == 2){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByPeriod (2).size () == 0)System.out.println ("There is no data corresponding");
                    this._output.println (this.getData.getDataByPeriod (2));
                }else{System.out.println("You are not connected to the database server");}


            }else if(Integer.parseInt (clientMsg) == 3){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByType (3).size () == 0)System.out.println ("There is no data corresponding");
                    this._output.println (this.getData.getDataByType (30));
                }else{System.out.println("You are not connected to the database server");}


            }else if(Integer.parseInt (clientMsg) == 4){
                int p = Integer.parseInt (clientMsg);
                this._output = new PrintWriter(this._socket.getOutputStream(), true);
                if (this.getData.connect ())
                {
                    if(this.getData.getDataByType (4).size () == 0)System.out.println ("There is no data corresponding");
                    this._output.println (this.getData.getDataByType (60));
                }else{System.out.println("You are not connected to the database server");}


            }else{

            }
        }
        this._input.close ();
        this._output.close ();
    }catch(IOException e){}

}

これらは私のサーバーを実行させる2つのクラスです。クラスClient.javaが起動し、接続を受け入れるのを待ちます。クライアントが接続すると、clientThreadのインスタンスが作成され、クライアントに関連付けられます。ここまで、すべてがうまく機能しているようです。

クライアント側

public class ServerConnect implements Runnable{

public static Socket clientSocket = null;
public static PrintWriter out = null;
public static BufferedReader in = null;
public static int port=9450;
public static String host = "127.0.0.1";
public static JLabel myLabel;
public static JButton button;
public static ResourceMap resourceMap;
private static String serverMsg = "";

public ServerConnect(JLabel jLabel, JButton b)
{
    jLabel.setText ("Trying to contact the server");
    myLabel = jLabel;
    button = b;
    port = Integer.parseInt("9450");
    host = "127.0.0.1";

        try{
            clientSocket = new Socket(host, port);
            }catch(IOException e){e.printStackTrace ();}

}

public void run()
{
    while(true){
        while(!this.connect ())
        {myLabel.setText ("You are not connected to the server : "+host);
         button.setEnabled (false);
            try{
                clientSocket = new Socket(host, port);
            }catch(IOException e){}
        }

        myLabel.setText ("You are connected to the server : "+host);
        button.setEnabled (true);
        try{
           out = new PrintWriter(clientSocket.getOutputStream(), true);
           out.println("@CONNECT");

           in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
           while((serverMsg = in.readLine ()) != null){
                System.out.println ("<=> :"+serverMsg);
           }
        }
        catch(IOException e){e.printStackTrace ();}
    }
}
private boolean connect()
{
    try{
        clientSocket = new Socket(host, port);
        return true;
    }catch(IOException e){}
    return false;
}}

私の問題は、両側が起動しているときに、クライアントが@CONNECTを送信する唯一のものであり、サーバーがそれを受信し、すべてがここで停止することです。クライアントが再度要求を送信した場合、サーバーは応答しません。 このアプリケーションをセットアップする方法(サーバー側)
を誰かに段階的に教えてもらいたいです。
WHILEループ
(クライアント側)とのスレッドでの接続を受け入れます。別のスレッドでは、接続を確立するために毎回サーバーに接続しようとします
-別のスレッドでは、クライアントはサーバーに要求を送信します
-サーバーは、データベースからの情報を要求し、クライアントに送り返す別のスレッドです。

よろしくお願いします

4

2 に答える 2

1

PrintWriter などを使用して低レベルのソケットにすべてを配置するのは悪い考えです。過去にいくつかのエンコーディング エラーとマルチスレッド エラーが発生しました。したがって、私の(もちろん少し遅いですが、使いやすい)解決策は、ジャージーとグリズリーです。

大きな利点は次のとおりです。転送コードを変更せずに、転送オブジェクトを非常に簡単に変更および拡張できます(低レベルのソケット書き込み)。

インターフェイス...

public interface I_ServiceCommons {
        public static final String  MEDIATYPE           = "text/xml";
        public static final String  MEDIATYPE_ENCODING  = I_ServiceCommons.MEDIATYPE + "; charset=utf-8";
        public static final String SERIVCENAME = "/FUNNY_SERVICE_V001";
    }

サーバー側のコード

@Path(I_ServiceCommons.SERIVCENAME)
public class YourService {

    @POST
    @Produces(I_ServiceCommons.MEDIATYPE)
    @Consumes(I_ServiceCommons.MEDIATYPE)
    public ResultObject request(final RequestObject yourRequest) {
        //process here your request in Server
    }
}

あなたのクライアント....

public class abstract YourAbstractClient{
        protected Logger                            log             = Logger.getLogger(this.getClass());
        protected final String                      serviceUrl;
        private final WebResource                   resource;

        public YourAbstractClient(final String url) {
            this.serviceUrl = url + getService();
            this.resource = Client.create().resource(this.serviceUrl);
        }

        public abstract String getService();

        protected <RES, REQ> RES post(final Class<RES> resultClazz, final REQ req) {
            final Builder builder = this.resource.type(I_ServiceCommons.MEDIATYPE).accept(I_ServiceCommons.MEDIATYPE);
            try {
                final RES result = builder.post(resultClazz, req);
                return result;
            } catch (final Exception e) {
                throw new RuntimeException("Error posting data to [" + this.serviceUrl + "]: " + e.getMessage(), e);
            }
        }

    }

あなたのServiceClient...

public class Service extends YourAbstractClient {

    public Service(final String url) {
        super(url);
    }

    public MyResult getResult(final MyRequest req) {
        return super.post(MyResult.class, req);
    }

    @Override
    public String getService() {
        return I_ServiceCommons.SERIVCENAME;
    }
}

あなたの TransferObject

@XmlRootElement
public class MyRequest implements Serializable {
    public void setRequestType(final int p_AequestType) {
        this.requestType = p_AequestType;
    }

    public int getRequestType() {
        return this.requestType;
    }
}

そして結末は…

String url = "http://127.0.0.1";
GrizzlyServerFactory.create(url) //starts the server
MyRequest res = new MyRequest();
MyResult result = new Service(url).getResult(req); // Corrected
于 2012-07-24T06:30:56.223 に答える
0

これは非常にシンプルですが、基盤となるテクノロジーは複雑です。;) 逆の順序で説明します (私の回答 @ https://stackoverflow.com/a/11625335/1268954 )。

メイン コードでは、「127.0.0.1」でリッスンする GrizzlyServerFactory.create(url) を使用して Grizzlyserver を開始します。

サーバーが起動すると、アノテーション @Path ... でクラスを検索し、「YourService」を見つけます。

そのため、Grizzly は URL " http://127.0.0.1/FUNNY_SERVICE_V001 "で ServiceClass "YourService" を "登録" (またはそのようなもの) します(I_ServiceCommons を参照)。

さて、再びメイン コードに戻ります。MyRequest オブジェクトを作成し、具体的なサービス「サービス」のインスタンスを作成します。クライアント側のコードであるため、より適切な名前は「ServiceClient」にする必要があります。「サービス」は URL (「http://127.0.0.1」) で作成され、YourAbstractClient の共通コンストラクター コード (すべてのクライアント用) にステップ インし、サービス URL「http://127.0.0.1/FUNNY_SERVICE_V001 」を作成します。" . YourAbstractClient 内にクライアント オブジェクト (接続/エンコード処理など) が作成されます。サーバーにアクセスする場合は、"サービス" の "getResult" メソッドに MyRequest オブジェクトを配置するだけです。クライアントYourAbstractClient の内部では、MyRequest オブジェクトを XML 再表現に変換し (@XMLRootElement アノテーション、パラメーターなしのコンストラクター、set/get メソッドに注意してください)、サーバーに対して HTTP POST を実行し、MyRequest オブジェクトを再作成します。

再びサーバー側で...クライアントが正しい方法で「http://127.0.0.1/FUNNY_SERVICE_V001」に接続すると、サーバーは YourService のインスタンスを作成し(パラメーターなしのコンストラクターが必要)、xmlを読み取り、 @POSTpublic ResultObject request(final RequestObject yourRequest)アノテーションでアノテーションが付けられているため (クライアントでは HTTP-POST を実行します)。MyReqeust オブジェクトを処理し、MyResult オブジェクトを返す必要があります。これは、xml に変換され、送信され、クライアントによって受信され、MyResult オブジェクトに再作成されます。それでおしまい。

于 2012-07-24T08:10:06.403 に答える