私の質問への回答がドキュメントへのポインタになることを期待しています。ただし、必要に応じて、バグ ハント用のコードを投稿できます。
自宅での作業を簡素化するために、単一の Wintel OS/コンピューターで、マイクロコントローラーで実行されるサーバーと Wintel PC で実行される Java クライアント間の相互作用をシミュレートしようとしています。シミュレーションが十分であれば、関係の PC 側のソフトウェアを開発するためだけにマイクロコントローラー機器を家に持ち帰る必要はありません。
したがって、1 台の Wintel コンピューター (自宅) の 1 台の JVM で、次のようにしました。
- backlog パラメーターを 0 に設定して、192.168.1.63:3456 (ローカル アドレスとローカル (既知の) ポート) にバインドされた新しい ServerSocket オブジェクトを作成しました。このオブジェクトは、通常マイクロコントローラーにあるコードを表します。
- 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: 念のため... この動作 (上記) を見たときに実行されていたコードはシングルスレッドです。完全に成功するには、マルチスレッド化する必要があると誰かが指摘する前に。そんなこと知ってる。とにかく、私は上で説明したことを期待していませんでした。