【发布时间】:2017-06-01 08:21:22
【问题描述】:
我的 Winsock Delphi 应用程序应该在所有网络接口上侦听多播 UDP/IP 流。它正常收听,直到我在另一台具有不同网络适配器优先级的 PC 上尝试。
然后我开始研究问题,在一些论坛上发现INADDR_ANY(或0.0.0.0)在Windows和Linux中的含义不同:
- 在 Linux it means "listen on all interfaces" 和发送 - 通过默认接口发送
- 在 Windows 中 it means "listen on default interface"(
0.0.0.1用于第二个)。引用:“如果此成员指定的 IPv4 地址为 0.0.0.0,则使用默认的 IPv4 多播接口”——没有提及它是用于侦听还是用于发送。
您能否确认或否认这一点?
如何在所有接口上真正聆听?
这是我的一小段代码:
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;
【问题讨论】:
标签: linux sockets delphi winsock multicast