2012-01-17 5 views
4

私はSunのJavaチュートリアルを実行しています。私はソケットについてのレッスン中です。単純なスレッドサーバーの場合、次のコードがあります。スレッドサーバーは、より多くの着信接続のためにポストで引き続きリッスンしますか?

import java.net.*; 
import java.io.*; 

public class KKMultiServer { 
    public static void main(String[] args) throws IOException { 
     ServerSocket serverSocket = null; 
     boolean listening = true; 

     try { 
      serverSocket = new ServerSocket(4444); 
     } catch (IOException e) { 
      System.err.println("Could not listen on port: 4444."); 
      System.exit(-1); 
     } 

     while (listening) 
     new KKMultiServerThread(serverSocket.accept()).start(); 

     serverSocket.close(); 
    } 
} 

サーバーは「受信接続をもっと引き続き」と言われています。私はちょうどそれが可能である方法を理解していません。 serverSocket.accept()は、Socketというオブジェクトを作成します。このオブジェクトは、チュートリアル「同じローカルポートににバインドされています。さて、サーバがクライアントと通信して、同じポート上のより多くの着信接続を待ち受けている可能性はありますか?私の知る限り、ポートがいくつかの接続に使用されていると、ポートはブロックされ、より多くのものに使用することはできません。

ここで何が間違っていますか?

+0

重複:http://stackoverflow.com/questions/489036/how-does-the-socket-api-accept-function-work – Kevin

答えて

2

使用されていないOSから割り当てられたポートを取得干渉するそれは(アドレス、ポート)のタプル上でユニークです。通信に関係するローカルソケットとリモートソケットのペアである接続は、ポートから正しいソケットへの受信データをデマルチプレクシングするために使用され、1つのポート上に複数のソケットを入れることができます。 See Wikipedia。つまり、ソケットとポートの関係はN対1です。

+0

新しいクライアントごとに新しいポートを割り当てたいのですか?それを行うための正しい方法は何ですか? –

+1

うーん、面白い質問...各クライアントは、静的な割り当て方式で事前にチェックするポートを知るか、サーバからポートを取得する必要があります。または、私は、ポートがオープンポートのためにスキャンするのをやっていると思います。とにかく、get-a-port-from-the-serverスキームでは、クライアントを既知のポートに接続させます。サーバーは割り当てられていないポートを開き、新しい接続情報で応答し、クライアントは新しいポートに再接続します。いずれにしても、これを行うための標準的な方法は認識していません(しかし、その存在を排除するものではありません)。これはすべてのアプリケーションレベルです。 – Matt

+0

この回答はソケットを接続と競合させるため、すべての点で間違っています。明確にするため、http://stackoverflow.com/questions/152457/what-is-the-difference-between-a-port-and-a-ソケット/152863#152863を参照してください。 –

0

クライアント(この例では、サーバは、ポート4444上の仮想的なマシンTARANISで実行されて起動し、このサーバーのホストとポートに接続を要求するまで、このlink

に基づく方法待機を受け入れるは)。接続がであり、正常に確立された場合、acceptメソッドは同じローカルポートにバインドされ、リモートアドレスとリモートポートがクライアントのものに設定された新しいSocketオブジェクトを返します。サーバーはこれを介してクライアントと通信できます新しいソケットと元のServerSocket上のクライアント接続要求をリッスンし続けるこの特定のバージョンのプログラムは、クライアント接続要求をさらに受信しません

ここでは、単一のポートが複数のクライアントコールをどのように処理するのかについての混乱を解消する可能性があります。Port and Socket SO discussion

簡単な言葉で言えば、ほとんどのWebサーバーはポート8080でリッスンし、複数のクライアントは同じポートにアクセスしてWebサイトにアクセスします。

1

各TCP接続が(ローカルホスト、ローカルポート、リモートホスト、リモートポート)タプルであるため、同じポートで複数の接続を行うことは全く可能です。少なくとも1が異なる限り、接続は区別され、 (帯域幅が低下するほか)、サーバーに接続しようとする

クライアントは一般的によく、ソケットは1対1のポートに基づいていない現在

1

リスニングソケットは、ビジネスの電話スイッチの受付係のように動作します。誰もがスイッチ番号に電話をかけ、他の誰かが別の回線でコールを処理するようにすることで、受付係はスイッチ回線上の各着信コールに応答します。受付係は一度に1回しか電話をかけることはできませんが、スイッチ回線はに接続してに接続するために非常に短時間で結ばれます。

[...] TCPは、ローカルおよび外部アドレスを構成する4つの値(宛先IPアドレス、宛先ポート番号、送信元IPアドレス、および送信元ポート番号)をすべて使用して、受信セグメントを多重分離します。 TCPは、宛先ポートのみを調べて着信セグメントを取得するプロセスを判別できません。また、着信接続要求を受信する[指定のポート番号]の[様々な]エンドポイントのうち、唯一のものがリッスン状態のものです。 (P255、TCP-IPイラスト1巻、W.リチャードスティーヴンス)は

上記の引用の最後の文章を理解するための鍵です。

興味深いことに、ソケットは実際にはIPアドレスとポートの組み合わせによって識別されません。これは、コンテキストが特定の接続またはリスニング状態の場合にのみ、コンテキスト内でユニークです。 1つのリスナーソケットだけが特定のIP /ポートの組み合わせにバインドできます。

0

短くて甘い答えは、ポートが他のプログラムやプロセスでブロックされていることです。ポートを開いたプログラムだけがこれでリッスンできます。しかし、それは同じポート上の多くの異なるクライアントを聞くことができます。

クライアントが接続すると、固有のソケットが作成されます。ソケットは、リッスンしているIPアドレスとポート(開いたもの)と呼び出し元のIPアドレスとポートで構成されます。発信者のIPアドレスとポートは常に一意であるため、各ソケットは一意であり、リスナーに識別されます。

同じマシンからプログラムに2回接続したとしても、私のマシンは接続ごとに新しい無作為のソースポートを選択し、毎回ユニークなソケットがあることを保証します。

関連する問題