了解从JDK8更改为JDK11的SocketAddress的本机代码

时间:2019-12-01 02:08:17

标签: c sockets ip

JDK8中的

net_util_md.h具有以下用于套接字地址的代码:

#ifdef AF_INET6

#define SOCKADDR        union { \
                            struct sockaddr_in him4; \
                            struct sockaddr_in6 him6; \
                        }

#define SOCKADDR_LEN    (ipv6_available() ? sizeof(SOCKADDR) : \
                         sizeof(struct sockaddr_in))

#else

#define SOCKADDR        union { struct sockaddr_in him4; }
#define SOCKADDR_LEN    sizeof(SOCKADDR)

#endif
现在,来自JDK11的

net_util_md.h具有用于套接字地址的以下代码:

typedef union {
    struct sockaddr     sa;
    struct sockaddr_in  sa4;
    struct sockaddr_in6 sa6;
} SOCKETADDRESS;

因此,在JDK8中,我可以将对SOCKADDR的引用转换为struck sockaddr *并与以下C代码进行比较:

int sockaddr_cmp(struct sockaddr *x, struct sockaddr *y)
{
#define CMP(a, b) if (a != b) return a < b ? -1 : 1

    CMP(x->sa_family, y->sa_family);

    if (x->sa_family == AF_UNIX) {
        struct sockaddr_un *xun = (void*)x, *yun = (void*)y;
        int r = strcmp(xun->sun_path, yun->sun_path);
        if (r != 0)
            return r;
    } else if (x->sa_family == AF_INET) {
        struct sockaddr_in *xin = (void*)x, *yin = (void*)y;
        CMP(ntohl(xin->sin_addr.s_addr), ntohl(yin->sin_addr.s_addr));
        CMP(ntohs(xin->sin_port), ntohs(yin->sin_port));
    } else if (x->sa_family == AF_INET6) {
        struct sockaddr_in6 *xin6 = (void*)x, *yin6 = (void*)y;
        int r = memcmp(xin6->sin6_addr.s6_addr, yin6->sin6_addr.s6_addr, sizeof(xin6->sin6_addr.s6_addr));
        if (r != 0) {
            return r;
         }
        CMP(ntohs(xin6->sin6_port), ntohs(yin6->sin6_port));
        CMP(xin6->sin6_flowinfo, yin6->sin6_flowinfo);
        CMP(xin6->sin6_scope_id, yin6->sin6_scope_id);
    } else {
        return -1;
    }

#undef CMP
    return 0;
}

如何使用JDK11中的新SOCKETADDRESS做同样的事情?

1 个答案:

答案 0 :(得分:0)

  

因此在JDK8中,我可以将SOCKADDR强制转换为struck sockaddr * [原文]

我想您是说您可以按照您的描述将指针投射到 SOCKADDR。那是合理的,但是强制转换SOCKADDR本身是不正确的。

好消息:您仍然可以像以前一样做很多事情。可以安全地将SOCKETADDRESS *强制转换为struct sockaddr *,并可以通过您现有的函数比较以这种方式获得的两个struct sockaddr *值。所提供的功能至少在这种情况下与在JDK 8情况下一样有效。 (哪种方法都不完全有效,但这是另一回事。)