IPv6数据包不在特定地址上接收,而是在Linux中的in6addr_any上接收,但在Windows中全部接收

时间:2019-01-11 09:46:59

标签: server udp ipv6

我已经在Windows和Linux中创建了IPv6 UDP服务器。 我在此处附加了相同的源代码以供查看。

此代码正在接收特定IPv6地址以及WINDOWS中的in6addr_any上的数据包。
但是,当我在linux上移植此代码时,仅当我设置sin.sin6_addr = in6addr_any;时,它才会接收数据包。
但是当我设置为inet_pton(AF_INET6, "2001:db8:21:333:250:baff:fed6:abe2", &sin.sin6_addr);时,它不会接收任何数据包,而在Windows中,这两种情况都可以接收。

附件的源代码已成功编译,没有警告。 请帮助我理解为什么这种行为仅在Linux中而不是Windows中是观察者。

源代码:-

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>

typedef struct
{

    int i32AddressFamily;
    int i32Type;
    int i32Protocol;

}Socket_Pkt_t;

int sid;
int num;

uint8_t g_u8RxBuf[MAX_MPDU] = { 0 };
uint8_t g_pstSrc[MAX_MPDU] = { 0 };

int main(void)
{
    struct sockaddr_in6 sin = { 0 };
    struct in6_addr stAddress = { 0 };
    struct ipv6_mreq mreq;
    Socket_Pkt_t stSocketPkt;
    fd_set stReadFds = {0};
    struct timeval stSelectTimeout = {0};
    struct sockaddr_in6 stSin = {0};
    socklen_t stSinLen = sizeof(stSin);
    int32_t i32RcvBytes = 0;
    long i32Max = 0;
    int reuseaddr = 1;

    stSocketPkt.i32AddressFamily = AF_INET6;
    stSocketPkt.i32Type = SOCK_DGRAM;
    stSocketPkt.i32Protocol = IPPROTO_UDP;

    sid = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);


    inet_pton(AF_INET6, "ff0e::bac0", &mreq.ipv6mr_multiaddr);
    mreq.ipv6mr_interface = if_nametoindex("eth0");
    num = setsockopt(sid, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char             *)&mreq,sizeof(mreq));
    //num = setsockopt(sid, SOL_SOCKET, SO_REUSEADDR,     &reuseaddr,sizeof(reuseaddr));

    memset(&sin, 0 ,sizeof(sin));
    sin.sin6_family = AF_INET6;
    sin.sin6_port = htons(47808);
    //inet_pton(AF_INET6, "2001:db8:21:333:250:baff:fed6:abe2",     &sin.sin6_addr.__in6_u.__u6_addr8[]);
    //sin.sin6_scope_id = 0x0e;
    sin.sin6_addr = in6addr_any;
    //2001:db8:21:333:12c3:7bff:fe4e:9edb
    inet_pton(AF_INET6, "2001:db8:21:333:250:baff:fed6:abe2",     &sin.sin6_addr);
    num = bind(sid, (const struct sockaddr *) &sin,sizeof(struct     sockaddr_in6));

    if(num < 0)
    {
        reuseaddr = errno;
        return -1;
    }

    /* calculate and save the time */
    stSelectTimeout.tv_sec = 1000 / 1000;
    stSelectTimeout.tv_usec = 1000 * (1000 - stSelectTimeout.tv_sec *     1000);

    i32Max = sid;
    while(1)
    {
        /* initialize the stReadFds to null */
        FD_ZERO(&stReadFds);

        /* add socket descriptor to stReadFds */
        FD_SET(sid, &stReadFds);

        num = select((int32_t)i32Max + 1, &stReadFds, NULL, NULL,      &stSelectTimeout);

        if(num > 0)
        {
            if(FD_ISSET(sid, &stReadFds))
                    {
                        /* clear read file descriptor */
                        FD_CLR(sid, &stReadFds);
                        FD_ZERO(&stReadFds);

                        i32RcvBytes = recvfrom(sid, (void *)g_u8RxBuf,     1506,
                                0, (struct sockaddr *) &stSin,     &stSinLen);

                        /* copy address i.e. from where the data is     received */
                        memcpy(g_pstSrc, &stSin, stSinLen);
                        printf("packet received ...\r\n");
                    }
        }
        else
        {
            /* clear read file descriptor */
            FD_CLR(sid, &stReadFds);
            //FD_CLR(BIP_GetSocketId_For_BroadComm(), &stReadFds);
            FD_ZERO(&stReadFds);
        }
    }
    return 0;
}

0 个答案:

没有答案