web-dev-qa-db-ja.com

ネットワークUDPブロードキャスト設計?

私のサーバー(LinuxでC++を実行)がメッセージをブロードキャストしてネットワーク全体で生きていることを示すC++サーバー/.NETクライアントアプリケーションの組み合わせに取り組んでおり、.NETプログラムはパケットをリッスンして解析し、稼働時間を取得しますサーバーの。

読んだように、通常のUDPブロードキャストをブロードキャストアドレスに送信するには、パケットを192.168.0.255(私の場合は192.168.2.255)または255.255.255.255に送信するだけです。これは正しいですか?同じポートアドレスを使用できますか?他に必要なものはありますか?

私の.NETプログラムがその特定のアドレスをリッスンする場合、私のC++サーバープログラム以外のアプリケーションからパケットを受信することが可能であることを理解しています。 .NETプログラムがパケットのヘッダーを読み取り、それが(ほぼ)探しているものであることを確認するために、C++サーバー側でパケットに「署名」する方法はありますか?

17
Andrei Zisu

あなたが使用している言語に関係なく、これが私の答えです:

ブロードキャストIPアドレスに関しては、どちらのアドレスもブロードキャストアドレスですが、制限されたブロードキャストアドレス(255.255.255.255)はルーターによって転送されません。サブネット向けのブロードキャストアドレス(192.168.2.255)を使用することをお勧めします。

ブロードキャストアドレスを送受信するには、ブロードキャストアドレス(ブロードキャストIPアドレスとポート番号)を定義する必要があります。例:192.168.2.255およびポート番号3000。クライアントアプリケーション(送信者)は、次のようにSO_BROADCASTソケットオプションを有効にする必要があります。

int enabled = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled));

ここで、sockfdはソケット記述子です。

サーバーアプリケーションは、特定のポート番号(ポート3000)でリッスンします。通常、サーバーはユニキャストメッセージを使用して各要求に応答します。

同じポート番号でリッスンしているアプリケーションがない限り、競合は発生しません。 SO_REUSEADDRESSソケットオプションを有効にしない限り、別のアプリケーションが同じポートでリッスンしている場合、サーバーは実行されません。ただし、競合がある場合、署名はプロトコル(メッセージ形式)に依存します。したがって、メッセージフォーマットを確認し、アプリケーションプロトコルで定義されているメッセージフォーマットに従っていない場合は、メッセージを拒否してください。

クライアントアプリケーションの場合、受信したパケットはユニキャストです(別の設計がない限り)。したがって、こちら側での競合はありません。

29
badawi

また、ブロードキャストトラフィックを送信するには、C++でSO_BROADCASTソケットオプションを有効にする必要があります。そうしないと、権限拒否エラーが発生します。

int broadcastPermission = 1;
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))
9
RedPeasant

.NETプログラムがブロードキャストトラフィックをリッスンしている場合、サーバーから送信されていないトラフィックを含め、そのポートで送信されたネットワーク上のすべてのブロードキャストトラフィックを受信します。サーバーから送信されたブロードキャストメッセージのペイロードに「マーカー」を置くことができます。このようにして、.NETプログラムはどのプログラムが対象かを区別できます。

さらに、ブロードキャストではなくマルチキャストを使用することをお勧めします。ブロードキャストトラフィックは通常、同じサブネット上のホストに制限されます。簡単に言えば、ネットワークにルーターがある場合、ルーターがサイドBのホストから送信されたブロードキャストトラフィックをルーターのサイドAのホストが見ることはありません(逆も同様です)。ホストがマルチキャストグループに参加している場合、ルーターはほとんど常にマルチキャストトラフィックを転送します。

3
Matt Davis