似乎没有可移植的方法来设置从绑定到INADDR_ANY的套接字发送UDP数据报的源IP,但至少在Linux和FreeBSD上可以使用sendmsg()
和IP_PKTINFO
完成( Linux)或IP_SENDSRCADDR
(FreeBSD)选项。 (见this question。)
是否有在Windows上设置UDP源IP的等效选项?
答案 0 :(得分:2)
来自MSDN:
WSASendMsg功能
[...]
在类型为
SOCK_DGRAM
或SOCK_RAW
的IPv4套接字上,应用程序可以使用WSASendMsg
函数指定用于发送的本地IP源地址。在WSAMSG
结构中传递给WSASendMsg
函数的控制数据对象之一可能包含in_pktinfo
结构,用于指定用于发送的本地IPv4源地址。
这同样适用于具有in6_pktinfo
结构的IPv6套接字。
对于双模插槽,重要的是不要将{IPv4}源地址指定为in6_pktinfo
中的IPv4映射IPv6地址,而应指定为in_pktinfo
结构中的IPv4地址。 / p>
union {
char in[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))];
char in6[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo))];
} cdata;
WSAMSG msg;
memset(&msg, 0, sizeof(msg));
msg.name = &remote_sysaddr.addr.generic;
msg.namelen = remote_sysaddr.len;
msg.lpBuffers = &buf;
msg.dwBufferCount = 1;
msg.Control.buf = (char *)&cdata;
msg.Control.len = sizeof(cdata);
int sum = 0;
WSACMSGHDR *cmsg = WSA_CMSG_FIRSTHDR(&msg);
...
memset(cmsg, 0, WSA_CMSG_SPACE(sizeof(struct in_pktinfo)));
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_PKTINFO;
cmsg->cmsg_len = WSA_CMSG_LEN(sizeof(struct in_pktinfo));
struct in_pktinfo *pktinfo = (struct in_pktinfo *)WSA_CMSG_DATA(cmsg);
pktinfo->ipi_addr.s_addr = local_addr->ipv4;
sum += WSA_CMSG_SPACE(sizeof(struct in_pktinfo));
...
msg.Control.len = sum;
if (bs->WSASendMsg(bs->socket, &msg, 0, &bytes, NULL, NULL) != 0) {
...
答案 1 :(得分:-2)
我认为this就是它。
UdpClient构造函数(IPEndPoint)
此构造函数创建一个新的UdpClient,并将其绑定到localEP参数指定的IPEndPoint。在调用此构造函数之前,必须使用要从中发送和接收数据的IP地址和端口号创建IPEndPoint。您无需为发送和接收数据指定本地IP地址和端口号。如果不这样做,底层服务提供商将分配最合适的本地IP地址和端口号。