0

現在、ソケットを使用して列車のチケット予約システムを設計しています。クライアントは、チケットの検索、チケットの予約、チケットのキャンセルを行うことができます。クライアントは、SearchRequest、BookRequest、CancelRequest などのさまざまなオブジェクトをサーバーに送信します。サーバー側では、各リクエストを処理するために 3 つのスレッドプールが必要です。これが検索リクエストの処理方法です。

searchserverSocket = new ServerSocket(search_portNum);
search_pool = Executors.newFixedThreadPool
              (Runtime.getRuntime().availableProcessors()*POOL_SIZE); 
public void service(){
        while(true){
            Socket search_socket = null;
            try{
                search_socket = searchserverSocket.accept();
                SearchHandler search_han = new SearchHandler(search_socket,search_request);

                search_pool.submit(search_han);

            }catch(IOException e){
                e.printStackTrace();
            }
        }   
    }

他の2つのリクエストを処理する方法が非常に混乱しています。別のポートで新しい ServerSocket を作成する必要がありますか? サーバーはどのようにして異なるタイプのリクエストを識別できますか?

4

2 に答える 2

0

ソケットからバイト ストリームを取得します。そのストリームを使用して、要求されているアクションを特定する必要があります。プロトコルを設計する必要があります。

Java クラスを使用してプロトコルを定義し、インスタンスをシリアル化し、バイトをソケットに書き込むことができますが、このタスクが与えられた場合はGoogle Protocol Bufferを使用します。たとえば、次のように各リクエスト タイプのメッセージを定義できます (必要なフィールドを推測しています)。

message Search 
{
  required string destination = 1;
  required string origin = 2;
  ...
}

message Book
{
  required int32 trainId = 1;
  required string destination = 2;
  required string origin = 3;   
  ...
}

message Cancel
{
  required int32 bookingId = 1;
  ...
}

プロトコルを定義するクラスがある場合、それらがソケットから得られるバイトの配列としてどのように表示されるかを考える必要があります。ここで重要なことは、サーバーがリクエストのストリームを受信することを期待して、フレーミングについて考えることです。2 つの一般的な方法があります。デリミタを使用して各メッセージの終わりをマークする方法と、各メッセージの前に固定バイト数でメッセージの長さを書き込む方法です。どちらにも長所と短所があります。

ソケットからメッセージを読み取ったら、リクエスト タイプをオンにして、適切なハンドラ クラスを呼び出すことができます。

于 2013-11-06T14:11:13.390 に答える