web-dev-qa-db-fra.com

Conception de diffusion réseau UDP?

Je travaille sur un couple d'applications client C++ serveur/.NET dans lequel mon serveur (qui exécute le c ++ sur linux) diffuse un message pour montrer qu'il est vivant sur l'ensemble du réseau et mon programme .NET écoute les paquets et analyse pour obtenir la disponibilité du serveur.

Comme je l'ai lu, pour envoyer une diffusion UDP régulière à l'adresse de diffusion, je dois simplement envoyer un paquet au 192.168.0.255 (dans mon cas 192.168.2.255) ou 255.255.255.255. Est-ce correct? Puis-je utiliser la même adresse de port? Y a-t-il d'autres nécessités?

Je comprends le fait que si mon programme .NET écoute sur cette adresse particulière, il est possible de recevoir des paquets provenant d'autres applications que mon programme serveur C++. Existe-t-il une méthode de "signature" du paquet côté serveur C++ pour que mon programme .NET puisse lire l'en-tête du paquet et voir que c'est (presque) celui que je recherche?

17
Andrei Zisu

Quelle que soit la langue que vous utilisez, voici ma réponse:

En ce qui concerne les adresses IP de diffusion, les deux adresses sont des adresses de diffusion mais l'adresse de diffusion limitée (qui est 255.255.255.255) ne sera pas transmise par les routeurs. Il est préférable d'utiliser l'adresse de diffusion dirigée vers le sous-réseau (192.168.2.255).

Pour envoyer/recevoir une adresse de diffusion, vous devez définir votre adresse de diffusion (adresse IP de diffusion et numéro de port). Par exemple: 192.168.2.255 et numéro de port 3000. Les applications clientes (les expéditeurs) DOIVENT activer l'option de socket SO_BROADCAST comme suit:

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

où sockfd est le descripteur de socket.

L'application serveur écoutera un numéro de port spécifique (port 3000). Normalement, le serveur répondra à chaque demande en utilisant un message unicast.

Il n'y aura pas de conflit tant qu'aucune application n'écoute sur le même numéro de port. Votre serveur ne s'exécutera pas si une autre application écoute sur le même port, sauf si vous avez activé l'option de socket SO_REUSEADDRESS. Cependant, en cas de conflit, votre signature dépend de votre protocole (format du message). Vérifiez donc le format du message et rejetez le message s'il ne respecte pas le format de message défini par votre protocole d'application.

Pour les applications client, le paquet reçu est unicast (sauf si vous avez une autre conception). Donc, pas de conflit de ce côté.

29
badawi

Vous devez également activer l'option de socket SO_BROADCAST en C++ pour envoyer du trafic de diffusion, ou vous obtiendrez une erreur d'autorisation refusée:

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

Si votre programme .NET écoute le trafic de diffusion, il recevra tout le trafic de diffusion sur le réseau envoyé sur ce port, y compris le trafic non envoyé par votre serveur. Vous pouvez mettre un "marqueur" dans la charge utile des messages diffusés envoyés par votre serveur. De cette façon, votre programme .NET pourrait distinguer ceux qui lui tiennent à cœur.

Au-delà de cela, je recommanderais d'utiliser la multidiffusion au lieu de la diffusion. Le trafic de diffusion est généralement limité aux hôtes du même sous-réseau. En termes simples, si vous avez un routeur dans votre réseau, un hôte du côté A du routeur ne verra pas le trafic diffusé envoyé par un hôte du côté B (et vice versa) car le routeur le "bloque". Les routeurs transfèrent presque toujours le trafic de multidiffusion si un hôte a rejoint le groupe de multidiffusion.

3
Matt Davis