2016-03-20 16 views
2

学習目的で、私はJava TCPサーバーを作成しています。これはSyteTCPServerという独自のクラスにラップされており、接続ロジックを処理するためにServerSocketを使用しています。これは良いコードプラクティスが非常に重要な学校プロジェクトのためのものです。Java TCPサーバークラスの抽象度

特定のアプリケーションレベルのプロトコルがあるため、独自のクラスに入れられている理由があります。クラスはより大きなプロジェクトの一部です。

グーグルでは、ServerSocketとそれに付随するロジックをすべてメインメソッド内に直接配置している人しか見つかりませんでした。私はそれがOOPになると行く方法はわからないのですか?

マイSyteTCPServer。しかしながら、単純なStart()Stop()方法は、それが顧客を扱う、ServerSocketを使用しての実装、などを隠し

を持って、私はので、ネットワーク機能の多くを困惑少しです、 IntelliJはIOExceptionsを捕まえるよう警告しています。クライアントを受け入れることによってIOExceptionがスローされる可能性があるので、前記クライアントの出力ストリームを得ることができるので、writeBytesができます。

抽象化のコンテキストでは、これらの例外をどのようにして解決するのが最適でしょうか?この方法の隣にthrows IOExceptionと書いて、上のコードtry...catchSyteTCPServer.Startにしますか?

また、サーバー停止全体で例外が発生した場合、またはクライアントの1つが正しく接続されなかったという事実を「非表示にする」必要がありますか?あるいは、クライアントが接続に失敗したときにイベントを発生させるべきでしょうか?私は本当に知りません..

UI /コアコードの分離のためにペストのような例外が発生した場合、出力を書き込むことも避けてください。

私はこれらが1つにあまりにも多くの質問ではないことを願っています。

はここで、私が持っているstartメソッドの例ですIOExceptionがスローされます。

public void Start() throws IOException { 
    this.listenSocket = new ServerSocket(this.port); 

    Listen(); 
} 

答えて

1

私はそれはあなたが受け取ることがあります異なるIOExceptionsを区別することが重要だと思います。たとえば、接続が確立されている間に新しい接続または接続を作成することは例外ですか、それはやや予期しないエラーですか?

をサーバソケットを構築するために:これはちょうどdocumentationを読んで、何が起こっている正確に何に応じてエラーを処理することであるため、最も簡単な方法

公共のServerSocket(int型ポート)にIOException

    をスローします
  • IOException - ソケットを開くときにI/Oエラーが発生した場合。
  • SecurityException - セキュリティーマネージャーが存在し、そのcheckListenメソッドが操作を許可しない場合
  • IllegalArgumentException - portパラメータが有効なポート値の指定された範囲(0〜65535の範囲)を超えている場合接続を受け入れるため

公共ソケットを受け入れる()は

  • にIOException

    をスローにIOException - 接続を待っているときにI/Oエラーが発生した場合。
  • SecurityException - セキュリティマネージャが存在し、そのcheckAcceptメソッドがこの操作を許可しない場合。
  • てSocketTimeoutException - タイムアウトが以前にsetSoTimeoutを使って設定されたタイムアウトに達した場合。
  • IllegalBlockingModeException - このソケットに関連するチャネルを有する場合、チャネルが非ブロッキングモードである、というように

を受け入れする準備ができない接続は存在しません。例外(複数可)をキャッチする場所について

:これはまた、あなたのサーバが特定のケースで何をしたいのかに依存します。しかし、一般的に、「予想される」エラーをキャッチしてそこで処理し、非意図的なエラーをより高いレベルに投げる。私はこれで何を意味

public void foo() throws IOException { 
    try { 
     serverSocket = new ServerSocket(PORT); 
    } catch (IOException e) { 
     // Port is in use -> perhaps retry on another port 
     // If things fail, throw exception anyway 
    } finally { 
     if (!serverSocket.isClosed()) { 
      try { 
       serverSocket.close(); 
      } catch (IOException e) { 
       // This exception is to be taken care of internally, not thrown 
      } 
     } 
    } 
} 

はまた、これは同様に、サーバ側のために、しかし、クライアント側のためだけではなく、適用可能であることに注意してください。

幸運サーバーを書きます!

1

私はすべてのServerSocketとそれに付随するロジックをメインメソッドの中に直接入れている人しか見つかりませんでした。私はそれがOOPになると に行く方法であるかどうかわからないのですか?直接間違いなく良いOOPの練習ではありませんmain()方法で、受け入れて処理し、クライアントへの読み取り/書き込みのようなすべてのServerSocket作成コードとそれに続くロジックを置く

。 OOPで

、我々は、オブジェクトの観点から考えるべきで、これらのオブジェクトがどのように相互作用するか所望の機能性を満たすために。そして、それぞれのオブジェクトは明確な責任をカプセル化します。

IOExceptionをスロー可能性があり、クライアントを受け入れ、そう言ったクライアントの 出力ストリームを取得でき、これのwriteBytes、..あなたは私のポイントを得ることができます。抽象化の文脈では

、どのように私は最高のこれらの の例外については行くのですか?メソッドの隣にIOExceptionをスローして、 を上位のコードにしようとします... SyteTCPServer.Startをキャッチしますか?私は

  • を強調表示することができ

いくつかのベストプラクティスは、デバッグおよび他の改善のために、後で必要不可欠なツールとなるように、すべての必要な情報を持つと例外をログに記録することを忘れないでください。

  • フローに沿って複数のtry/catchで同じ例外を捕捉しないでください。
  • 例外を捕まえた後に飲み込んだり、本当に必要な場合を除き、例外を再投げたりしないでください。
  • 最後に、例外を処理する方法は、回復可能な例外かどうかによっても異なります。回復不能な場合は例外を記録し、リソースをクリーンアップします。回復可能な場合は例外をログに記録し、例外から回復する手順に従います。そして、ここでの最良のガイドは、そのAPIのjavadocです。また
  • 、サーバ全体の停止は、すべての例外が発生しなければならない、または私は 「隠す」のいずれかのクライアントが正常に接続しなかったという事実すればよいですか?または おそらく、クライアントが接続に失敗したときにイベントを発生させる必要がありますか?

    あなたがコードを実装沿って行くと、私は他のように、そのうちの一つが、別のスレッドで、各クライアントの接続要求を処理するために、可能性があり、ClientConnectionHandlerオブジェクト(スレッド)を言う、あなたも複数のクラスを見つけると確信していますクライアントはブロックされません。したがって、各クライアント接続は独立した実行スレッドになります。

    この設計では、例外がそのクライアント接続に固有のものである場合、サーバー全体を停止する必要はありません。そのクライアントスレッドを終了してリソースをクリーンアップするだけで十分です。