3

SSDPメッセージを送受信する必要があるUPnP AV / DLNA DMSを作成しています。いくつかのパケットに応答して、リソース (この場合は HTTP サーバー) の URL を含む応答を送信する必要があります。もちろん、このアドレスはパケットの送信者には意味がありません。パケットを受信したインターフェイスのアドレスが最も適切です。M-SEARCHINADDR_ANY0.0.0.0M-SEARCHM-SEARCH

応答パケットで送信する適切なアドレスを特定するにはどうすればよいですか?

私が検討したいくつかのアイデアは次のとおりです。

  1. 各ソケットに異なるレシーバーをバインドします。受信者がM-SEARCHパケットを受信すると、応答アドレスは応答でソケットのローカル アドレスを使用できます。ただし、これには、すべてのインターフェイスを把握して反復し、インターフェイスの可用性の変化に応じてレシーバーを追加および削除する必要があります。
  2. に 1 つのレシーバを配置しINADDR_ANY、インターフェイスのネットマスクを反復して、考えられるソースを特定します。ただし、複数のインターフェースが同じサブネットを共有する場合があります。
  3. 受信時にパケットの IP ターゲット アドレスを抽出します。これは IP 固有のものであり、ネットワークの抽象化のどこかで失われる可能性があります。
4

1 に答える 1

2

getsockname(2)続いgetnameinfo(3)て、TCP/IPスタックがソケットに割り当てたIPアドレスを報告します。(明らかに、これは、サーバーとクライアントがNATシステムの反対側にある場合にクライアントが使用できるものとは一致しません。その場合、クライアントがサーバーに接続するために使用できるIPアドレスを検出するための巧妙なUPnPトリックが存在する可能性があります。 。)

サーバーは次のようになっていると思います。

lfd = socket();
ret = bind(lfd,...);
connection = listen(lfd, 10);
/* add connection to your select queue or poll queue */

次のようなコードを追加できます。

struct sockaddr_storage me;
socklen_t *len = sizeof(me);
char name[40];
ret = getsockname(connection, &me, &len);
ret = getnameinfo(&me, &len, name, sizeof(name), NULL, 0, NI_NUMERICHOST);

getnameinfo(3)IPアドレスを検査します。これらは汎用インターフェイスであるため、IPv4またはIPv6アドレスで機能します。struct sockaddr_storage me

于 2011-03-04T12:45:55.373 に答える