2

クライアントをサーバーに接続するJavaプログラムがあります。これには、クライアントがメッセージを送信してサーバーをトリガーした後のファイル ディレクトリの作成が含まれます。例: サーバーが既に実行されている場合、クライアントは接続し、「Your message: Lady」というメッセージを送信します。サーバーは、「Request to create a Directory named: Lady」のようなメッセージを受信します。この後にディレクトリLady という名前で作成されます。

しかし問題は、この接続が 1 対 1 のみであるということです。サーバーに接続できるのは1つのクライアントだけのように...

サンプルコードは次のとおりです。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package today._;

import java.io.*;

import java.net.*;

import java.text.*;

import java.util.*;

public class myServer {

    protected static final int PORT_NUMBER = 55555;

    public static void main(String args[]) {

        try {

            ServerSocket servsock = new ServerSocket(PORT_NUMBER);

            System.out.println("Server running...");

            while (true) {
                Socket sock = servsock.accept();
                System.out.println("Connection from: " + sock.getInetAddress());
                Scanner in = new Scanner(sock.getInputStream());
                PrintWriter out = new PrintWriter(sock.getOutputStream());
                String request = "";
                while (in.hasNext()) {
                    request = in.next();
                    System.out.println("Request to Create Directory named: " + request);

          if(request.toUpperCase().equals("TIME")) {  
                    try {
                        File file = new File("C:\\" + request);
                        if (!file.exists()) {
                            if (file.mkdir()) {
                                System.out.println("Directory is created!");
                            } else {
                                System.out.println("Failed to create directory!");
                            }
                        }
                    } catch (Exception e) {
                        System.out.println(e);
                    }
                    out.println(getTime());

                    out.flush();
          } else {
               out.println("Invalid Request...");                     
               out.flush();
          }
                }

            }


        } catch (Exception e) {
            System.out.println(e.toString());
        }

    }

    protected static String getTime() {
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        return (dateFormat.format(date));
    }
}

package today._;

import java.io.*;

import java.net.*;

import java.util.*;

 public class myClient {

        protected static final String HOST = "localhost";
        protected static final int PORT = 55555;

        protected static Socket sock;

        public static void main(String args[]) {

        try {

              sock = new Socket(HOST,PORT);

              System.out.println("Connected to " + HOST + " on port " + PORT);

              Scanner response = new Scanner(sock.getInputStream());
              PrintWriter request = new PrintWriter(sock.getOutputStream());
              BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
              String txt = "";

              while(!txt.toUpperCase().equals("EXIT")) {

                    System.out.print("Your message:");
                    txt = in.readLine();

                    request.println(txt);
                    request.flush();

                    System.out.println(response.next());

              }

              request.close();
              response.close();
              in.close();
              sock.close();

           } catch(IOException e) {
              System.out.println(e.toString());
           }
      }

 }
4

2 に答える 2

2

マルチクライアント サーバーは、通常、次の 2 つの方法のいずれかで記述されます。

  1. クライアントごとにスレッドを作成します。これを行うには、サーバー ソケットで accept() の呼び出しを処理するスレッドを作成し、それが返す Socket で呼び出しを処理する新しいスレッドを生成します。これを行う場合は、各ソケットのコードを可能な限り分離する必要があります。受け入れスレッドは永久に、またはフラグが設定されるまでループし、accept を呼び出し、新しいソケットでスレッドを生成し、accept の呼び出しに戻ります。すべての作業は子スレッドにあります。

  2. NIO または別のテクノロジーを使用して、作業をさらに 1 つのスレッドに多重化します。NIO は select と呼ばれることもある概念を使用します。この概念では、特定のソケットから利用可能な入力がある場合にコードが呼び出されます。

小規模なサーバーを実行している場合は、最も単純な設計を使用でき、クライアントもあまり多くないため、#1 を使用します。大規模な運用サーバーを実行している場合は、#2 を実行するのに役立つ netty や jetty などのフレームワークを検討します。NIO は扱いにくい場合があります。

いずれの場合も、スレッドとファイル システムには十分注意してください。同時実行パッケージのロック、同期、または別のロック スキームを使用しないと、期待した結果が得られない可能性があります。

私の最後のアドバイスは、クライアントがサーバーにファイルシステムで何かをするように指示することに注意してください。とは言っても、それは危険なことです;-)

于 2013-07-14T08:25:22.567 に答える
1

サーバー クラスは、すべての接続を処理するために複数のスレッドを使用する必要があります。

class MyServer {


    private ServerSocket servsock;

    MyServer(){
        servsock = new ServerSocket(PORT_NUMBER);
    }

    public void waitForConnection(){
        while(true){
            Socket socket = servsock.accept();
            doService(socket);
        }
    }

    private void doService(Socket socket){
        Thread t = new Thread(new Runnable(){
            public void run(){
                while(!socket.isClosed()){
                    Scanner in = new Scanner(sock.getInputStream());
                    PrintWriter out = new PrintWriter(sock.getOutputStream());
                    String request = "";
                    // and write your code
                }
            }
        });
        t.start();
    }
}
于 2013-07-14T08:29:46.720 に答える