JavaでTFTP (簡易 FTP)プロトコルを実装しています。クライアントとサーバーがあり、これまでのところ、クライアントはファイルを要求でき、サーバーはそのデータをクライアントに送信します。
ここで問題が発生しました。明らかなテスト上の理由から、マシンでクライアントとサーバーの両方を実行しています。ただし、ファイルを送信するときは、同じポートでリッスンする 2 つのソケットが必要です。
- クライアントは、受信したデータ パッケージをリッスンする必要があります
- サーバーはクライアントの確認応答をリッスンする必要があります
...そして、データと確認応答を送信するための 2 つのそれぞれのソケットも、ポートを共有します。
これは通常、同じポートで発生しますが、別のマシンで発生します。これを回避し、醜いハックなしで、クライアントとサーバーの両方を同じホスト上で平和的に動作させる方法はありますか? そして、醜いハックとは、次のようなことを意味します。
- ACK通信ポートの事前定義されたオフセット(データポートの+15など。これは私が現在使用しているものです。機能しますが、間違っているように感じ、エラーが発生しやすいです)
ソケットの開閉を繰り返します (データを送信し、データの送信に使用されたソケットを閉じて、クライアントがそのポートを使用して ACK を送信できるようにするなど)。これは現時点でも機能しますが、ハック経由でも機能します。たとえば、送信に使用されるソケットを「再度開く」方法は次のとおりです。
public void open() { 試す { ソケット = 新しい DatagramSocket(localPortCache); } キャッチ (SocketException e) { e.printStackTrace(); } }
これは悪です。私のソケットは、元々、動的に割り当てられた一時的なポート番号を受け取ります。次に、その値を記憶し、それを使用してソケットを古いポートに「復元」します。ただし、そのポートがまだ使用可能であることは保証できません。通常はそうですが、保証はありません。この場合、私は過度に妄想的ですか?
- ハンドシェイクで新しい ACK 通信ポートを生成し、追加の手順で制御ポート (69) 経由でクライアントに送信します。
アップデート:
私は自分の問題を解決することができました。私の問題は、ソケットを再利用しようとしていないことでした。たとえば、ポート X のソケットから何かを送信しましたが、古いソケットを再利用する代わりに、そのポートに新しいソケットを割り当てて ACK をリッスンしようとしました。