1

私の質問への回答がドキュメントへのポインタになることを期待しています。ただし、必要に応じて、バグ ハント用のコードを投稿できます。

自宅での作業を簡素化するために、単一の Wintel OS/コンピューターで、マイクロコントローラーで実行されるサーバーと Wintel PC で実行される Java クライアント間の相互作用をシミュレートしようとしています。シミュレーションが十分であれば、関係の PC 側のソフトウェアを開発するためだけにマイクロコントローラー機器を家に持ち帰る必要はありません。

したがって、1 台の Wintel コンピューター (自宅) の 1 台の JVM で、次のようにしました。

  1. backlog パラメーターを 0 に設定して、192.168.1.63:3456 (ローカル アドレスとローカル (既知の) ポート) にバインドされた新しい ServerSocket オブジェクトを作成しました。このオブジェクトは、通常マイクロコントローラーにあるコードを表します。
  2. 192.168.1.63:3456 および 192.168.1.63:0 (リモート アドレス、リモート ポート、ローカル アドレス、ローカル ポート (一時ポートのプレースホルダー)) にバインドされた新しい (クライアント) Socket オブジェクトを作成しました。このオブジェクトは、Wintel コンピュータに通常存在するコード/オブジェクトを表します。

ServerSocket の accept() メソッドを呼び出すまで、上記の項目 2 での新しいソケットの作成がブロックされる (接続されない) ことを期待していました。代わりに、Socket 作成の試行 (および Socket の暗黙的な接続試行) により、新しい (クライアント) Socket オブジェクトがすぐに生成されました。私の(クライアント)コードの実行は続きました(次のいくつかの命令は.setReuseAddress(true)、.getInputStream()、.getOutputStream()などでした)。

私がJava APIドキュメントで読んだことはすべて、明示的または暗黙的に、ServerSocketのaccept()呼び出しは、ソケットがServerSocket(実際にはServerSocketが作成する新しいソケットに...)への接続プロセスを完了できるようにするものであると述べています。しかし、私の Socket は、ServerSocket の accept() 呼び出しの前にレースに出ました。

誰かが私が見ていることの説明を教えてもらえますか (クライアントの接続試行は、サーバーによる accept() の前に完了します)?

この説明が、適切なシミュレーション (クライアントとサーバーの両方が 1 台のコンピューターにあるという理由だけで特別なコードを必要としないもの) を作成する方法を教えてくれるものになることを願っています。

PS: 念のため... この動作 (上記) を見たときに実行されていたコードはシングルスレッドです。完全に成功するには、マルチスレッド化する必要があると誰かが指摘する前に。そんなこと知ってる。とにかく、私は上で説明したことを期待していませんでした。

4

1 に答える 1

3

0 のバックログ パラメータ

プラットフォームによって上下に調整されます。Javadoc を参照してください。バックログの最小値が 5 を下回ったことはなく、一部のプラットフォームでは現在 50 または 500 になっています。

私が Java API ドキュメントで読んだことはすべて、明示的または暗黙的に、ServerSocket の accept() 呼び出しが、ソケットが ServerSocket への接続プロセスを完了できるようにするものであると述べています。

何などすべて?引用を提供してください。この誤った信念を正当化する文書はどこにもありません。によって返されるソケットはaccept()、クライアントの観点からはすでに完全に形成されている可能性がある接続を表します。それがバックログ キューの目的です。

(実際には、ServerSocket が作成する新しいソケットに...); しかし、私の Socket は、ServerSocket の accept() 呼び出しの前にレースに出ました。

接続は TCP スタックによって完了され、バックログ キューに置かれました。がaccept()行ったことは、エンドポイントとしてローカル ソケットを作成することだけでした。

これはすべて正常です。あなたの期待は間違っていました。

「それらの両方を汚す」場合は、コードにバグがあります。クライアントが接続を完了して要求を送信し、サーバーが呼び出す前に応答を待機することは、まったく正常です。accept().

于 2015-02-18T21:27:14.167 に答える