Mon application Delphi Winsock doit écouter sur toutes les interfaces réseau le flux UDP/IP multidiffusion. Il a écouté normalement jusqu'à ce que je l'ai essayé sur un autre PC avec l'ordre de priorité des différents adaptateurs de réseau.Différence entre INADDR_ANY sous Linux et la programmation de socket Windows
Alors j'ai commencé à problème de recherche et a trouvé sur certains forums qui INADDR_ANY
(ou 0.0.0.0
) a un sens différent dans Windows et Linux:
- Dans Linux it means "listen on all interfaces" et pour envoyer - envoyer par l'interface par défaut
- Dans Windows it means "listen on default interface" (
0.0.0.1
pour le second). Citation: "Si ce membre spécifie une adresse IPv4 de 0.0.0.0, l'interface de multidiffusion IPv4 par défaut est utilisée" - sans mentionner si c'est pour l'écoute ou pour l'envoi.
Pourriez-vous confirmer ou infirmer cela?
Comment écouter vraiment sur toutes les interfaces?
Voici un petit morceau de mon code:
TMulticastListener = class(TThread)
private
mreq: ip_mreq;
............
end;
constructor TMulticastListener.Create;
var err: Integer;
wData: WsaData;
reuse: Integer;
begin
inherited Create(true);
err := WSAStartup(MAKEWORD(2, 2), wData);
if err = SOCKET_ERROR then begin
// Tell the user that we could not find a usable Winsock DLL
perror('WSAStartup');
Exit;
end;
// create what looks like an ordinary UDP socket
fd := socket(AF_INET, SOCK_DGRAM, 0);
if fd = INVALID_SOCKET then begin
perror('socket');
Exit;
end;
reuse := 1;
// allow multiple sockets to use the same PORT number
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, Pointer(@reuse), SizeOf(reuse)) < 0) then begin
perror('Reusing ADDR failed');
Exit;
end;
// set up destination address
FillChar(addr, sizeof(addr), 0);
addr.sin_family := AF_INET;
addr.sin_addr.s_addr := htonl(INADDR_ANY); // N.B.: differs from sender
addr.sin_port := htons(HELLO_PORT);
// bind to receive address
if (bind(fd, addr, sizeof(addr)) < 0) then begin
perror('bind');
Exit;
end;
// use setsockopt() to request that the kernel join a multicast group
mreq.imr_multiaddr.s_addr := inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr := htonl(INADDR_ANY); //inet_addr('0.0.0.0');
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, @mreq, sizeof(mreq)) < 0) then begin
perror('setsockopt');
Exit;
end;
end;
Merci. J'ai fourni le code complet. Va lire le tien à la maison. – Paul