2

INADDR_ANYにバインドされたソケットからUDPデータグラムを送信するためのソースIPを設定する移植可能な方法はないようですが、少なくともLinuxおよびFreeBSDではsendmsg()IP_PKTINFO(Linux)またはIP_SENDSRCADDR(FreeBSD)オプションを使用して行うことができます。(この質問を参照してください。)

WindowsでUDPソースIPを設定するための同等のオプションはありますか?

4

2 に答える 2

2

MSDNから:

WSASendMsg関数

[...]

SOCK_DGRAMタイプまたはのIPv4ソケットではSOCK_RAW、アプリケーションは、関数で送信するために使用するローカルIP送信元アドレスを指定できWSASendMsgます。WSAMSG構造体で関数に渡される制御データオブジェクトの1つに、送信に使用するローカルIPv4送信元アドレスを指定するために使用される構造体WSASendMsgが含まれている場合があります。in_pktinfo

同じことが構造を持つIPv6ソケットにも当てはまりますin6_pktinfo

デュアルモードソケットの場合、IPv4送信元アドレスがでIPv4にマップされたIPv6アドレスとしてではなく、構造体in6_pktinfoでIPv4アドレスとして指定されていることが重要です。in_pktinfo


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 に答える