57

TCP における bind() の正確な機能を知りたかったのです。ローカルアドレスをソケットに「バインド」するとはどういう意味ですか? ソケットにポート番号を割り当てているのなら、クライアントでそれを使用しないのはなぜですか? クライアント側でOSによってポートが自動的に割り当てられることは知っていますが、これらすべてがどのように機能するかについての全体像はわかりません。

bind() の後、listen() します。bind は listen() とどのように関連していますか? bind() が実行されたことを listen() は認識しますか? もしそうなら、 bind() はそれが知られるようにどのような変更を加えますか? つまり、実行が成功した場合にゼロを返すと、どのように役立つのでしょうか?

私は多くの定義を調べてきましたが、これらすべてを詳細に把握できる場所はありません。誰かが私にこれを説明してくれれば、私は感謝します。

4

4 に答える 4

31

「ローカル」エンドのポート番号を割り当てます。

サーバーソケットの場合、これが究極の方法です。これはまさに必要なことです。たとえば、ソケットを Web サーバーのポート 80 にバインドします。

ただし、クライアント ソケットの場合、通常、ローカル アドレスとポートは重要ではありません。だからあなたはしませんbind()。サーバーがクライアントに特定のポート番号、または特定の範囲外のポート番号を持つように制限する場合は、bind()クライアント側でも使用できます。

一方、listen()呼び出していないソケットでも同様に実行できる可能性がありますbind()(実際にはそれについてはわかりませんが、それは理にかなっています)。このシナリオでは、サーバー ポートはランダムになり、サーバー プロセスはそのポートを別の手段でクライアントに通知します。制御接続とデータ接続がある、FTP などの「二重接続」プロトコルを想像してみてください。データ接続がリッスンするポートは完全に任意ですが、反対側に通信する必要があります。そこで「自動判別ポート」を使って通信します。

Python での一例:

import socket
s = socket.socket() # create your socket
s.listen(10) # call listen without bind
s.getsockname() Which random port number did we get?
# here results in ('0.0.0.0', 61372)

s2 = socket.socket() # create client socket
s2.connect(('localhost', 61372)) # connect to the one above
s3, x = s.accept() # Python specific use; s3 is our connected socket on the server side
s2.getpeername()
# gives ('127.0.0.1', 61372)
s2.getsockname()
# gives ('127.0.0.1', 54663)
s3.getsockname()
# gives ('127.0.0.1', 61372), the same as s2.getpeername(), for symmetry
s3.getpeername()
#gives ('127.0.0.1', 54663), the same as s2.getsockname(), for symmetry
#test the connection
s2.send('hello')
print s3.recv(10)
于 2012-10-06T19:55:14.843 に答える
17

bind()接続のローカル ポートとインターフェイス アドレスを定義します。 以前に実行されていない場合connect()は暗黙的に実行します (ゼロは「任意」と見なされます)。bind("0.0.0.0", 0)

発信接続の場合、これは一般に受け入れられ、推奨されます。OS は単純に「すべてのインターフェイス」にバインドし、番号の大きい未使用のポートを選択します。サーバーが特定のポートまたはポート範囲から来ることを期待している場合にのみ、クライアントでバインドする必要があります。一部のサービスは、1024 未満のポート番号からの接続のみを許可し、スーパーユーザーのみがバインドできますが、最近では誰もが自分のマシンを制御しているため、あまり意味がありません。

着信接続の場合、既知のポートにバインドして、クライアントが連絡先を知る必要があります。そうしたら、サーバーにローカルアドレス/ポートを与えて、通信が双方向に流れるようにします。 listen()通話後にのみ機能しbind()ます。

UDP、TCP、その他のいずれであっても、すべてのソケットはバインドする必要があります。常に明示的に行われるとは限りません。

于 2012-10-07T13:54:55.680 に答える
11

ソケットをアドレスに「バインド」します。そうしないと、リッスンする必要があるアドレス (IP アドレス/ポートのペア) がわかりません。

またbind、クライアント側でも使用できます。1 つの例として、複数のネットワーク カードが同じネットワークに接続されているコンピュータで、クライアントが 1 つの特定のネットワーク アドレスから来ているように見せたい場合があります。

バインディングは、TCP ソケットだけでなく、UDP ソケットやその他のプロトコルにも使用されます。

于 2012-10-06T19:55:04.323 に答える