2

UDPの「コネクションレス」の側面により、私はループに陥りました...

UDPソケットをINADDR_ANYに設定し、それをローカルマシンのポート33445にバインドすると、マシンはさまざまなクライアントからの着信接続を受け入れます。これはTCPではなく、各接続を直接処理するための新しい子ソケットを生成できないため、これらの接続はすべてその1つのソケットによって処理されます。これらの接続されたクライアントのいずれか、一部、またはすべてに、最新のメッセージから返信できます。

だから私にとって物事が少し曖昧になるところはここにあります...

これらのクライアントのいずれかにいつでもメッセージを送信できますか?または、recvfrom()に応答するメッセージのみを送信できますか?

これとは別に、そのサーバー(クライアントにサービスを提供している間)が別のサーバーに接続して他のことについて会話したい場合、この目的のために新しいソケットを作成する必要があると思いますか?既存のサーバーソケットを使用して新しい宛先アドレスを指定することはできませんか?

この素晴らしいコミュニティに感謝します。

編集:別の言い方をすれば、バインドされたソケットは、以前にそのソケットで私に到達したクライアントに応答するためにのみ使用できるようです。新しいホストとの会話を開始するために、バインドされたソケットをその目的に単純に使用することはできませんか?リッスンしているサーバーに到達するには、新しいソケットを作成する必要がありますよね?

4

2 に答える 2

3

UDPソケットは、次の2つの異なるモードで動作できます。

  • デフォルトの非接続モード:プロセスのポート/アドレスに送信されたすべてのデータグラムが受信されます。送信するたびに宛先アドレスを指定する必要があります。
  • 接続モード:接続したアドレス/ポートから送信されたデータグラムのみが受信されます。送信ごとに宛先アドレスを指定する必要はありません。

これは、接続されたUDPソケットの簡単なレビューです。

編集:

これは、任意のクライアントからのパケットを受け取り、それらを2番目のサーバーにコピーする小さなPythonUDPサーバーです。すべては、接続されていない1つのUDPソケットで実行されます。

#!/usr/bin/env python
import sys, socket, string

if len( sys.argv ) != 4:
        print "Usage: udptee <local-listen-port> <copy-host> <copy-port>"
        exit( 1 )

copy = ( sys.argv[2], int( sys.argv[3] ))

s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
#s.bind(( 'localhost', int( sys.argv[1] )))
s.bind(( '', int( sys.argv[1] )))

print "listening on ", s.getsockname()
print "copying to", copy

while True:
        line, addr = s.recvfrom( 1024 )
        print "received: ", line, " from ", addr
        s.sendto( line, addr ) # echo to source
        s.sendto( line, copy ) # copy to tee
        if string.strip( line ) == "exit": break

print "Goodbye and thanks for all the fish"
s.close()

1つのターミナルで次のように実行します。

~$ ./udptee 9090 <IP-of-copy-server> 9999

次にnetcat、第2期にサーバーモードで起動します。これはデータグラムのコピーを受け入れます:

# this used to be "nc -ul 127.0.0.1 9999" which only listened on loopback
~$ nc -ul 9999

クライアントを第3項で起動netcatして、最初のサーバーにデータを送信します。

~$ nc -u <IP-of-tee-server> 9090

入力を開始し、両方のサーバーが入力内容をエコーすることを確認します。

于 2010-08-09T13:50:49.863 に答える
1

UDPソケットはリモートホストまたはクライアントに接続されていないため、必要なのは、宛先アドレスと初期化したUDPソケットを使用してsendto()を使用することだけです。そうです、UDPソケットを正しく設定していれば、いつでもUDPソケットを使用してメッセージを送信できます。使用しているsockaddr構造体に受信アドレスを設定するだけです。受信側がメッセージを送信しているポートにバインドされたUDPソケットを持っている場合、それを受信します。

その2番目の質問では、その2番目のサーバーとの会話が別のポートを使用しているかどうかによって異なります。同じポートを使用する場合は、別のUDPソケットを作成する必要はありません。サーバー1がクライアントから取得するメッセージと、サーバー2から取得するメッセージを何らかの方法で分離する必要があります。

Beejの優れたガイドの第5.8章と第6.3章をご覧になることをお勧めします。

Beejのネットワークプログラミングガイド

于 2010-08-09T08:54:21.587 に答える