似乎没有可移植的方法来设置从绑定(bind)到 INADDR_ANY 的套接字发送 UDP 数据报的源 IP,但至少在 Linux 和 FreeBSD 上可以使用 sendmsg()
和 IP_PKTINFO
(Linux) 或 IP_SENDSRCADDR
(FreeBSD) 选项。 (参见 this question。)
在 Windows 上是否有等效的选项来设置 UDP 源 IP?
最佳答案
来自 MSDN :
WSASendMsg function
[...]
On an IPv4 socket of type
SOCK_DGRAM
orSOCK_RAW
, an application can specific the local IP source address to use for sending with theWSASendMsg
function. One of the control data objects passed in theWSAMSG
structure to theWSASendMsg
function may contain anin_pktinfo
structure used to specify the local IPv4 source address to use for sending.
这同样适用于具有 in6_pktinfo
结构的 IPv6 套接字。
对于双模式套接字,重要的是 IPv4 源地址不是在 in6_pktinfo
中指定为 IPv4 映射的 IPv6 地址,而是在 in_pktinfo< 中指定为 IPv4 地址
结构。
Example :
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) {
...
关于c++ - 如何在 Windows 上设置 UDP 源地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15657974/