导航:[首页]->[network]->[Socket 工具程序]

经常要测试socket程序,写几个工具来发送/接收报文

IPv4 UDP客户端

#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>

#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <errno.h>
#include <assert.h>

#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
typedef SOCKET socket_t;
#else
typedef int socket_t;
#define  INVALID_SOCKET  -1
#define closesocket close
#endif

int main(int argc,const char** argv)
{

#ifdef WIN32
    WSADATA wsaData = {0};
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

    if(argc < 4)
    {
        printf("%s des_ip des_port [ src_ip src_port ] content\n",argv[0]);
        return -1;
    }
    socket_t fd_ = socket(AF_INET,SOCK_DGRAM,0);
    if(fd_ == INVALID_SOCKET)
    {
        printf("socket error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }
    struct sockaddr_in addr_;
    addr_.sin_family = AF_INET;
    addr_.sin_addr.s_addr = inet_addr(argv[1]);
    addr_.sin_port = htons(atoi(argv[2]));

    if(!strcmp(argv[2],"255.255.255.255"))
    {
        int flag_ = 1;
        if(setsockopt(fd_, SOL_SOCKET,
                    SO_BROADCAST, (char*)&flag_, sizeof(flag_)) < 0) {
            closesocket(fd_);
            return -1;
        }
    }

    const char* msg_ = argv[3];
    if(argc > 5)
    {
        msg_ = argv[5];
        struct sockaddr_in addr2_;
        addr2_.sin_family = AF_INET;
        addr2_.sin_addr.s_addr = inet_addr(argv[3]);
        addr2_.sin_port = htons(atoi(argv[4]));

        if(!!bind(fd_,(const struct sockaddr*)&addr2_,sizeof(addr2_)))
        {
            printf("bind error '%d|%s'\n",errno,strerror(errno));
            return -1;
        }
    }

    if(sendto(fd_,msg_,strlen(msg_)+1,
            0,
            (struct sockaddr*)&addr_,
            sizeof(addr_)) < 0)
    {
        printf("send error '%d|%s'\n",errno,strerror(errno));
    }
    return 0;
}

IPv4 UDP服务器

#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Mswsock.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>

#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <errno.h>
#include <assert.h>

#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
typedef SOCKET socket_t;
#else
typedef int socket_t;
#define  INVALID_SOCKET  -1
#define closesocket close
#endif


int main(int argc,const char** argv)
{
#ifdef WIN32
    WSADATA wsaData = {0};
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

    if(argc < 2)
    {
        printf("%s port\n",argv[0]);
        return -1;
    }
    socket_t fd_ = socket(AF_INET,SOCK_DGRAM,0);
    if(fd_ < 0)
    {
        printf("socket error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    int flag_ = 1;
    if(setsockopt(fd_, IPPROTO_IP, IP_PKTINFO, (char*)&flag_,
                sizeof(flag_)) < 0)
    {
        printf("setsockopt error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

#ifndef WIN32
    struct ifaddrs * ifaddr_ = NULL;
    if(!!getifaddrs(&ifaddr_))
    {
        printf("getifaddrs error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    while (ifaddr_ != NULL) {
        if (ifaddr_->ifa_addr &&
                ifaddr_->ifa_name &&
                ifaddr_->ifa_addr->sa_family == AF_INET) 
        { 
            struct ifreq ifstruct_;
            memset(&ifstruct_,0,sizeof(ifstruct_));
            int ret_ = snprintf(ifstruct_.ifr_name,
                    sizeof(ifstruct_.ifr_name),
                    "%s",
                    ifaddr_->ifa_name);
            if (ret_ <= 0 ||
                    ret_ >= sizeof(ifstruct_.ifr_name) ||
                    ioctl(fd_, SIOCGIFINDEX, &ifstruct_) < 0)
            {
                printf("snprintf or ioctl error '%d|%s'\n",errno,strerror(errno));
                return -1;
            }

            struct sockaddr_in* addrptr_ =
                (struct sockaddr_in*)(ifaddr_->ifa_addr);
            printf("eth '%s' with ip '%s' ifindex '%d'\n",
                    ifaddr_->ifa_name,
                    inet_ntoa(addrptr_->sin_addr),
                    ifstruct_.ifr_ifindex);
        }
        ifaddr_ = ifaddr_->ifa_next;
    }
    freeifaddrs(ifaddr_);
#else
    GUID guid_wsa_recvmsg_ = WSAID_WSARECVMSG;
    LPFN_WSARECVMSG lpfn_wsarecvmsg_ = NULL;
    DWORD outsize_ = 0;
    WSAIoctl(
        fd_,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &guid_wsa_recvmsg_,
        sizeof(guid_wsa_recvmsg_),
        &lpfn_wsarecvmsg_,
        sizeof(lpfn_wsarecvmsg_),
        &outsize_,
        NULL,
        NULL
        );
    if (lpfn_wsarecvmsg_ == NULL)
    {
        return -1;
    }
#endif

    struct sockaddr_in addr_;
    addr_.sin_family = AF_INET;
    addr_.sin_port = htons(atoi(argv[1]));
    addr_.sin_addr.s_addr = inet_addr("0.0.0.0");

    if(!!bind(fd_,(const struct sockaddr*)&addr_,sizeof(addr_)))
    {
        printf("bind error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    struct sockaddr_in addr2_;
    char buf_[65536];
    char cmbuf_[0x100];
    do
    {
#ifndef WIN32
        struct iovec msg_iov_ =
        {
            .iov_base = buf_,
            .iov_len = sizeof(buf_)
        };
        struct msghdr mh_ = {
            .msg_name = &addr2_,
            .msg_namelen = sizeof(addr2_),
            .msg_iov = &msg_iov_,
            .msg_iovlen = 1,
            .msg_control = cmbuf_,
            .msg_controllen = sizeof(cmbuf_),
        };
        int ret_ = recvmsg(fd_,&mh_,0);
#else       
        WSABUF wsa_bufdata_;
        WSAMSG wsa_msg_;
        wsa_bufdata_.buf = buf_;
        wsa_bufdata_.len = sizeof(buf_);
        wsa_msg_.name = (sockaddr *)&addr2_;
        wsa_msg_.namelen = sizeof(addr2_);
        wsa_msg_.lpBuffers = &wsa_bufdata_;
        wsa_msg_.dwBufferCount = 1;
        wsa_msg_.Control.buf = cmbuf_;
        wsa_msg_.Control.len = sizeof(cmbuf_);
        wsa_msg_.dwFlags = 0;

        DWORD recvd_cnt_ = 0;
        if (0 != lpfn_wsarecvmsg_(fd_, &wsa_msg_, &recvd_cnt_, NULL, NULL))
        {
            printf("lpfn_wsarecvmsg_ fail '%d|%s'\n",errno,strerror(errno));
            continue;
        }
        int ret_ = (int)recvd_cnt_;
#endif
        if(ret_ > 0)
        {
            struct sockaddr_in toaddr_;
            socklen_t toaddr_len_ = sizeof(toaddr_);
            if(!!getsockname(fd_,
                        (struct sockaddr*)(&toaddr_),
                        &toaddr_len_))
            {
                printf("getsockname error '%d|%s'\n",errno,strerror(errno));
                return -1;
            }
#ifndef WIN32
            struct cmsghdr *cmsg_ = CMSG_FIRSTHDR(&mh_);
            struct in_pktinfo *pi_ = NULL;
            for (;cmsg_ != NULL;cmsg_ = CMSG_NXTHDR(&mh_, cmsg_))
            {
                if (cmsg_->cmsg_level == IPPROTO_IP &&
                        cmsg_->cmsg_type == IP_PKTINFO)
                {
                    pi_ = (struct in_pktinfo *)(CMSG_DATA(cmsg_));
                    break;;
                }
            }
            if(!pi_)
            {
                printf("invalid in_pktinfo '%d|%s'\n",errno,strerror(errno));
                continue;
            }
#else           
            WSACMSGHDR *pcmsg_hdr_ = WSA_CMSG_FIRSTHDR(&wsa_msg_);
            if(!pcmsg_hdr_ || 
                IP_PKTINFO != pcmsg_hdr_->cmsg_type
                || !(WSA_CMSG_DATA(pcmsg_hdr_)))
            {
                printf("WSA_CMSG_FIRSTHDR fail '%d|%s'\n",errno,strerror(errno));
                continue;
            }
            IN_PKTINFO *pi_ = (IN_PKTINFO *)WSA_CMSG_DATA(pcmsg_hdr_);
#endif
            toaddr_.sin_addr = pi_->ipi_addr; 
            printf("recv from [%d|%s] to ",                
                ntohs(addr2_.sin_port),                                        
                inet_ntoa(addr2_.sin_addr)); 
            printf("[%d|%s|%d] '%d' | '%s'\n",                                      
                ntohs(toaddr_.sin_port),                                       
                inet_ntoa(pi_->ipi_addr),                                   
                pi_->ipi_ifindex,                                              
                ret_,
                buf_); 
        }
        else if(ret_ == 0)
        {
            printf("empty recv error '%d|%s'\n",errno,strerror(errno));
        }
        else
        {
            printf("recv error '%d|%s'\n",errno,strerror(errno));
        }
    }while(1);
    return 0;
}

IPv4 RAW客户端

#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>
#include <netinet/ip.h>
#include <netinet/udp.h>


#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <errno.h>
#include <assert.h>

#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
typedef SOCKET socket_t;
typedef char flag_t;
#else
typedef int socket_t;
#define  INVALID_SOCKET  -1
#define closesocket close
typedef int flag_t;
#endif

#define PCKT_LEN 8192

unsigned short csum(unsigned short *addr, int nleft)
{
    unsigned sum = 0;
    while (nleft > 1) {
        sum += *addr++;
        nleft -= 2;
    }

    if (nleft == 1) {
        if (0)
            sum += *(uint8_t*)addr;
        else
            sum += *(uint8_t*)addr << 8;
    }

    sum = (sum >> 16) + (sum & 0xffff);   
    sum += (sum >> 16);      
    return (uint16_t)~sum;
}

int main(int argc,const char** argv)
{

#ifdef WIN32
    WSADATA wsaData = {0};
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

    if(argc < 8)
    {
        printf("%s ethname mac des_ip des_port src_ip src_port content\n",argv[0]);
        return -1;
    }
    socket_t fd_ = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
    if(fd_ == INVALID_SOCKET)
    {
        printf("socket error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    struct ifreq ifstruct;
    memset(&ifstruct, 0, sizeof(ifstruct));
    strcpy(ifstruct.ifr_name, argv[1]);
    if (ioctl(fd_, SIOCGIFINDEX, &ifstruct) < 0) 
    {
        printf("ioctl error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    struct sockaddr_ll addr_ll_;
    memset(&addr_ll_, 0, sizeof(addr_ll_));
    addr_ll_.sll_family = AF_PACKET;
    addr_ll_.sll_protocol = htons(ETH_P_IP);
    addr_ll_.sll_ifindex = ifstruct.ifr_ifindex;
    unsigned char mac[6];
    sscanf(argv[2],
            "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
            &mac[0], &mac[1], &mac[2],
            &mac[3], &mac[4], &mac[5]);
    addr_ll_.sll_halen = 6;
    memcpy(addr_ll_.sll_addr, mac, 6);

    char buffer[PCKT_LEN];
    // Our own headers' structures
    struct iphdr*ip = (struct iphdr*) buffer;
    struct udphdr* udp = (struct udphdr*) (buffer
            + sizeof(struct iphdr));
    char * payload = (buffer + sizeof(struct iphdr)
            + sizeof(struct udphdr));
    memset(buffer, 0, PCKT_LEN);
    int contentlen_ = strlen(argv[7]);
    snprintf(payload, contentlen_+1, "%s", argv[7]);

    ip->ihl = 5;
    ip->version = 4;
    ip->tos = 16; 
    ip->id = htons(54321);
    ip->ttl = 255; 
    ip->protocol = IPPROTO_UDP; 
    ip->saddr = inet_addr(argv[5]);
    ip->daddr = inet_addr(argv[3]);
    udp->source = htons(atoi(argv[6]));
    udp->dest = htons(atoi(argv[4]));
    udp->len = htons(sizeof(struct udphdr) + contentlen_ + 1);
    udp->check = 0;
    unsigned short len_ = sizeof(struct iphdr) +
        sizeof(struct udphdr) + contentlen_ + 1;
    ip->tot_len = htons(len_);
    ip->check = csum((unsigned short *) buffer, sizeof(struct iphdr));

    if(sendto(fd_, buffer, len_, 0, 
                (struct sockaddr *)&addr_ll_, sizeof(addr_ll_)) < 0)
    {
        printf("sendto error '%d|%s'\n",errno,strerror(errno));
    }
    return 0;
}

IPv6 UDP客户端

#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>

#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <errno.h>
#include <assert.h>

#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
typedef SOCKET socket_t;
#else
typedef int socket_t;
#define  INVALID_SOCKET  -1
#define closesocket close
#endif

int main(int argc,const char** argv)
{

#ifdef WIN32
    WSADATA wsaData = {0};
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

    if(argc < 4)
    {
        printf("%s des_ip des_port [ src_ip src_port ] content\n",argv[0]);
        return -1;
    }
    socket_t fd_ = socket(AF_INET6,SOCK_DGRAM,0);
    if(fd_ == INVALID_SOCKET)
    {
        printf("socket error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }
    struct sockaddr_in6 addr_;
    memset(&addr_,0,sizeof(addr_));
    addr_.sin6_family = AF_INET6;
    if(1 != inet_pton(AF_INET6, argv[1],(void*)&(addr_.sin6_addr)))
    {
        printf("inet_pton fail with ip string '%s'\n",argv[1]);
        return -1;
    }
    addr_.sin6_port = htons(atoi(argv[2]));

    const char* msg_ = argv[3];
    if(argc > 5)
    {
        msg_ = argv[5];

        int flag_ = 1;
        if(setsockopt(fd_, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&flag_,
                    sizeof(flag_)) < 0)
        {
            printf("setsockopt IPV6_V6ONLY failed with fd '%d'\n",fd_);
            return -1;
        }

        struct sockaddr_in6 addr2_;
        addr2_.sin6_family = AF_INET6;
        if(1 != inet_pton(AF_INET6, argv[3],(void*)&(addr2_.sin6_addr)))
        {
            printf("inet_pton fail with ip string '%s'\n",argv[3]);
            return -1;
        }
        addr2_.sin6_port = htons(atoi(argv[4]));

        if(!!bind(fd_,(const struct sockaddr*)&addr2_,sizeof(addr2_)))
        {
            printf("bind error '%d|%s'\n",errno,strerror(errno));
            return -1;
        }
    }

    if(sendto(fd_,msg_,strlen(msg_)+1,
            0,
            (struct sockaddr*)&addr_,
            sizeof(addr_)) < 0)
    {
        printf("send error '%d|%s'\n",errno,strerror(errno));
    }
    return 0;
}

IPv6 UDP服务器

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <errno.h>
#include <assert.h>

#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Mswsock.h>
#else

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define  __USE_GNU 
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>


#endif

#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
typedef SOCKET socket_t;
#else
typedef int socket_t;
#define  INVALID_SOCKET  -1
#define closesocket close
#endif


int main(int argc,const char** argv)
{
#ifdef WIN32
    WSADATA wsaData = {0};
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

    if(argc < 2)
    {
        printf("%s port\n",argv[0]);
        return -1;
    }
    socket_t fd_ = socket(AF_INET6,SOCK_DGRAM,0);
    if(fd_ < 0)
    {
        printf("socket error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    // http://www.spinics.net/lists/linux-man/msg01544.html
    int flag_ = 1;
#ifdef WIN32
    if(setsockopt(fd_, IPPROTO_IPV6, IPV6_PKTINFO, (char*)&flag_,
#else
    if(setsockopt(fd_, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char*)&flag_,
#endif
                sizeof(flag_)) < 0)
    {
        printf("setsockopt error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }
    flag_ = 1;
    if(setsockopt(fd_, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&flag_,
                sizeof(flag_)) < 0)
    {
        printf("setsockopt IPV6_V6ONLY failed with fd '%d'\n",fd_);
        return -1;
    }


#ifndef WIN32
    struct ifaddrs * ifaddr_ = NULL;
    if(!!getifaddrs(&ifaddr_))
    {
        printf("getifaddrs error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }

    while (ifaddr_ != NULL) {
        if (ifaddr_->ifa_addr &&
                ifaddr_->ifa_name &&
                ifaddr_->ifa_addr->sa_family == AF_INET6) 
        { 
            struct ifreq ifstruct_;
            memset(&ifstruct_,0,sizeof(ifstruct_));
            int ret_ = snprintf(ifstruct_.ifr_name,
                    sizeof(ifstruct_.ifr_name),
                    "%s",
                    ifaddr_->ifa_name);
            if (ret_ <= 0 ||
                    ret_ >= sizeof(ifstruct_.ifr_name) ||
                    ioctl(fd_, SIOCGIFINDEX, &ifstruct_) < 0)
            {
                printf("snprintf or ioctl error '%d|%s'\n",errno,strerror(errno));
                return -1;
            }

            struct sockaddr_in6* addrptr_ =
                (struct sockaddr_in6*)(ifaddr_->ifa_addr);
            char ipbuf_[128];
            printf("eth '%s' with ip '%s' ifindex '%d'\n",
                    ifaddr_->ifa_name,
                    inet_ntop(AF_INET6,(const void*)&(addrptr_->sin6_addr),ipbuf_,sizeof(ipbuf_)),
                    ifstruct_.ifr_ifindex);
        }
        ifaddr_ = ifaddr_->ifa_next;
    }
    freeifaddrs(ifaddr_);
#else
    GUID guid_wsa_recvmsg_ = WSAID_WSARECVMSG;
    LPFN_WSARECVMSG lpfn_wsarecvmsg_ = NULL;
    DWORD outsize_ = 0;
    WSAIoctl(
        fd_,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &guid_wsa_recvmsg_,
        sizeof(guid_wsa_recvmsg_),
        &lpfn_wsarecvmsg_,
        sizeof(lpfn_wsarecvmsg_),
        &outsize_,
        NULL,
        NULL
        );
    if (lpfn_wsarecvmsg_ == NULL)
    {
        return -1;
    }
#endif

    struct sockaddr_in6 addr_;
    memset(&addr_,0,sizeof(addr_));
    addr_.sin6_family = AF_INET6;
    addr_.sin6_port = htons(atoi(argv[1]));
    if(1 != inet_pton(AF_INET6, "::",(void*)&(addr_.sin6_addr)))
    {
        printf("inet_pton fail with ip string '%s'\n","::");
        return -1;
    }

    if(!!bind(fd_,(const struct sockaddr*)&addr_,sizeof(addr_)))
    {
        printf("bind error '%d|%s'\n",errno,strerror(errno));
        return -1;
    }


    struct sockaddr_in6 addr2_;
    char buf_[65536];
    char cmbuf_[0x100];
    do
    {
#ifndef WIN32
        struct iovec msg_iov_ =
        {
            .iov_base = buf_,
            .iov_len = sizeof(buf_)
        };
        struct msghdr mh_ = {
            .msg_name = &addr2_,
            .msg_namelen = sizeof(addr2_),
            .msg_iov = &msg_iov_,
            .msg_iovlen = 1,
            .msg_control = cmbuf_,
            .msg_controllen = sizeof(cmbuf_),
        };
        int ret_ = recvmsg(fd_,&mh_,0);
#else       
        WSABUF wsa_bufdata_;
        WSAMSG wsa_msg_;
        wsa_bufdata_.buf = buf_;
        wsa_bufdata_.len = sizeof(buf_);
        wsa_msg_.name = (sockaddr *)&addr2_;
        wsa_msg_.namelen = sizeof(addr2_);
        wsa_msg_.lpBuffers = &wsa_bufdata_;
        wsa_msg_.dwBufferCount = 1;
        wsa_msg_.Control.buf = cmbuf_;
        wsa_msg_.Control.len = sizeof(cmbuf_);
        wsa_msg_.dwFlags = 0;

        DWORD recvd_cnt_ = 0;
        if (0 != lpfn_wsarecvmsg_(fd_, &wsa_msg_, &recvd_cnt_, NULL, NULL))
        {
            printf("lpfn_wsarecvmsg_ fail '%d|%s'\n",errno,strerror(errno));
            continue;
        }
        int ret_ = (int)recvd_cnt_;
#endif
        if(ret_ > 0)
        {
            struct sockaddr_in6 toaddr_;
            socklen_t toaddr_len_ = sizeof(toaddr_);
            if(!!getsockname(fd_,
                        (struct sockaddr*)(&toaddr_),
                        &toaddr_len_))
            {
                printf("getsockname error '%d|%s'\n",errno,strerror(errno));
                return -1;
            }
#ifndef WIN32
            struct cmsghdr *cmsg_ = CMSG_FIRSTHDR(&mh_);
            struct in6_pktinfo *pi_ = NULL;
            for (;cmsg_ != NULL;cmsg_ = CMSG_NXTHDR(&mh_, cmsg_))
            {
                if (cmsg_->cmsg_level == IPPROTO_IPV6 &&
                        cmsg_->cmsg_type == IPV6_PKTINFO)
                {
                    pi_ = (struct in6_pktinfo*)(CMSG_DATA(cmsg_));
                    break;;
                }
            }
            if(!pi_)
            {
                printf("invalid in_pktinfo '%d|%s'\n",errno,strerror(errno));
                continue;
            }
#else           
            WSACMSGHDR *pcmsg_hdr_ = WSA_CMSG_FIRSTHDR(&wsa_msg_);
            if(!pcmsg_hdr_ || 
                IPV6_PKTINFO != pcmsg_hdr_->cmsg_type
                || !(WSA_CMSG_DATA(pcmsg_hdr_)))
            {
                printf("WSA_CMSG_FIRSTHDR fail '%d|%s'\n",errno,strerror(errno));
                continue;
            }
            IN6_PKTINFO *pi_ = (IN6_PKTINFO *)WSA_CMSG_DATA(pcmsg_hdr_);
#endif
            char ipbuf_[128];
            printf("recv from [%d|%s] to ",               
                ntohs(addr2_.sin6_port),                                       
                inet_ntop(AF_INET6,(void*)&(addr2_.sin6_addr),ipbuf_,sizeof(ipbuf_)));
            printf("[%d|%s|%d] '%d' | '%s'\n",                                     
                ntohs(toaddr_.sin6_port),                                      
                inet_ntop(AF_INET6,(void*)&(pi_->ipi6_addr),ipbuf_,sizeof(ipbuf_)),
                pi_->ipi6_ifindex,                                             
                ret_,
                buf_);
        }
        else if(ret_ == 0)
        {
            printf("empty recv error '%d|%s'\n",errno,strerror(errno));
        }
        else
        {
            printf("recv error '%d|%s'\n",errno,strerror(errno));
        }
    }while(1);
    return 0;
}

参考

  1. http://stackoverflow.com/questions/5281409/get-destination-address-of-a-received-udp-packet
  2. http://blog.csdn.net/my3439955/article/details/8905893