2

There seems to be no portable way to set the source IP for sending UDP datagrams from sockets bound to INADDR_ANY, but at least on Linux and FreeBSD it can be done using sendmsg() and the IP_PKTINFO (Linux) or IP_SENDSRCADDR (FreeBSD) option. (See this question.)

Is there an equivalent option to set the UDP source IP on Windows ?

4

2 回答 2

2

From MSDN:

WSASendMsg function

[...]

On an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP source address to use for sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg function may contain an in_pktinfo structure used to specify the local IPv4 source address to use for sending.

The same applies to an IPv6 socket with the in6_pktinfo structure.

For dual-mode sockets, it is important that an IPv4 source address is not specified as an IPv4-mapped IPv6 address in the in6_pktinfo, but as an IPv4 address in the in_pktinfo structure.


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) {
    ...
于 2013-06-29T13:23:54.803 回答
-2

我想就是这样

UdpClient 构造函数 (IPEndPoint)

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

于 2013-06-29T01:33:20.793 回答