Windows下如何设置UDP源地址

Howto set the UDP source address on Windows

本文关键字:设置 UDP 源地址 何设置 Windows      更新时间:2023-10-16

似乎没有可移植的方法来设置从绑定到INADDR_ANY的套接字发送UDP数据报的源IP,但至少在Linux和FreeBSD上可以使用sendmsg()IP_PKTINFO (Linux)或IP_SENDSRCADDR (FreeBSD)选项来完成。(参见这个问题)

是否有一个等效的选项来设置UDP源IP在Windows上?

From MSDN:

<

WSASendMsg函数/strong>

[…]

SOCK_DGRAMSOCK_RAW类型的IPv4套接字上,应用程序可以使用WSASendMsg函数指定发送使用的本地IP源地址。在WSAMSG结构中传递给WSASendMsg函数的控制数据对象之一可能包含in_pktinfo结构,用于指定用于发送的本地IPv4源地址。

同样适用于in6_pktinfo结构的IPv6套接字。

对于双模套接字,重要的是IPv4源地址不能在in6_pktinfo中指定为IPv4映射的IPv6地址,而是在in_pktinfo结构中指定为IPv4地址。


例子:

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) {
    ...

我想就是这样了。

UdpClient Constructor (IPEndPoint)

这个构造函数创建一个新的UdpClient并将其绑定到由localEP参数指定的IPEndPoint。在调用此构造函数之前,必须使用打算从中发送和接收数据的IP地址和端口号创建一个IPEndPoint。发送和接收数据时不需要指定本地IP地址和端口号。如果不这样做,底层服务提供者将分配最合适的本地IP地址和端口号。