12

私は最近、Javaを使用したソケットプログラミングに飛び込みましたが、いくつかの一般的な質問があります。

bind()メソッド、およびconnect()とdisconnect()があります。unbind()はありません。これは、切断時にソケットがバインドされていないためですか?プログラムが終了すると、ガベージコレクションはこれを処理しますか?それとも、これは有効な質問でもありませんか?

また、DatagramSocketを作成するときに、ポートとアドレスのみを指定した場合、どのように異なりますか?私は、データが浮かんでログに記録されるときに、ネットワークからデータを収集するプログラムを作成しています。ローカルアドレスだけを使用する必要がありますか?ソケットの作成時にアドレスを使用できなかったため、パケットを収集できませんでしたか?

私はこれらのものの内部の働きについてより深く理解しようとしているだけです。

4

2 に答える 2

16

そこには約15の独立した質問がありますが、私はそれらに対処するために最善を尽くします。

bind()メソッド、およびconnect()とdisconnect()があります。unbind()はありません。これは、切断時にソケットがバインドされていないためですか?

bind()connect()およびとは別disconnect()です。バインドは、ソケットを特定のポートにバインドするために使用されます。つまり、接続を「リッスン」するために効果的にconnect()使用されますが、特定のポートですでにリッスンしているソケットへの接続を開くために使用されます。に相当するものunbind()close()

プログラムが終了すると、ガベージコレクションはこれを処理しますか?それとも、これは有効な質問でもありませんか?

ガベージコレクションはメモリ管理に使用されるテクノロジであり、ソケット/ OSリソース管理ではありませんが、これは完全に有効な質問です。特定のポートを解放しない場合、アプリケーションが終了するまでそのポートはアプリケーションに関連付けられたままになり、その後OSによって再利用されます。これはOSレベルの機能であり、JVM機能などではありません。

また、DatagramSocketを作成するときに、ポートのみを提供する場合と、ポートとアドレスを提供する場合の違いは何ですか?

ある時点で、接続またはバインドするインターネットアドレスとポートまたはソケットを指定する必要があります。それを回避する方法はありません。

私は、データが浮かんでログに記録されるときに、ネットワークからデータを収集するプログラムを作成しています。ローカルアドレスだけを使用する必要がありますか?ソケットの作成時にアドレスを使用できなかったため、パケットを収集できませんでしたか?

ここで何を求めているのかわかりません。ネットワーク上のすべてのパケット、別名スニファをログに記録することについて話しているのですか?それには、単純なデータグラムプログラミング以上のものが必要になります。パケットが回線から読み取られるときにパケットを傍受するには、実際にはネットワークアダプタレベルで自分自身を注入する必要があります。あなたが話していることは、あなたが聞いている特定のポートに送信されたパケットを受信することだけを許可します。

于 2011-06-15T17:35:57.037 に答える
12

DatagramSocket切断されたときにバインドされたままのAは、バインドを解除するclose()メソッドです。UDP(データグラム)ソケットの場合、およびのセマンティクスはTCP(または他のコネクション型)ソケットconnect()とは異なることに注意してください。disconnect()UDPはコネクションレス型プロトコルであり、バウンドDatagramSocketは「接続」されていなくてもパケットを送受信できます。このconnect()方法は、ソケットが特定のホスト/ポートに対してのみパケットを送受信できるようにする、つまりフィルターとして機能するという点で、純粋にローカルな効果があります。マルチキャストまたはブロードキャストアドレスに接続されているDatagramSocket場合、パケットを送信することはできますが、受信することはできません。

bind(SocketAddress)ソケットをローカルアドレス/ポートの組み合わせに接続するために使用されます。ソケットがバインドされる前は、パケットを送受信できません。コンストラクターのデフォルトの動作は、ソケットをすぐにバインドすることです。バインドされていない'DatagramSocket'を作成するには、引数としてDatagramSocket(SocketAddress)渡すコンストラクターを使用します。null次に、でバインドする前に、任意のカスタム構成をソケットに適用できますbind()

スコープ外のオープンがリソースリークを引き起こすことがわかっている限りDatagramSocket、オブジェクトはガベージコレクションされる可能性がありますが、JVMプロセスが終了するまで、基盤となるUDPソケットはOSによって割り当てられたままになると確信しています。

ソケットがバインドされる前にアドレスが指定されていない場合、バインドされるとワイルドカードアドレス(INADDR_ANY)に接続され、使用可能なローカルアドレスからパケットを送受信できるようになります(後で何らかのホストに「接続」されている場合を除く)。ポートが指定されていない(または0として指定されている)場合、ソケットはOSによって選択された使用可能なポート(エフェメラルポート)にバインドされます。

編集:例

// bind to INADDR_ANY, allowing packets on all IP addresses of host:
DatagramSocket dsock = new DatagramSocket(55555);
DatagramPacket packet = new DatagramPacket(new byte[8192]);

//next packet can be from anywhere including local host (127.0.0.0/8)
dsock.receive(packet);

// restrict communication to a single host/port:
dsock.connect(new InetSocketAddress("somehost.net", 99));

// next packet can only be from somehost.net on port 99:
dsock.receive(packet);
于 2011-06-15T18:22:40.600 に答える