JNI实现一组字节数组转IP地址、IP地址转数组的函数

为什么单独实现,这是因为JAVA标准库提供的函数有性能问题,它会走DNS查询有网络IO,而且还是同步阻塞的,无论是客户端还是服务器,这都应该是不被允许的行为。

JNI实现:

 bytes_to_address_string(byte[] address) 字节转IP地址字符串

string_to_address_bytes(string address)  IP地址字符串转字节

// package: com.app.android.c
// public final class libxxx 
// public native string bytes_to_address_string(byte[] address)
__LIBXXX__(jstring) Java_com_app_android_c_libxxx_bytes_1to_1address_1string(JNIEnv* env, jobject this_, jbyteArray address_) {
    __LIBXXX_MAIN__

    if (NULL == address_) {
        return env->NewStringUTF("0.0.0.0");
    }

    int length = env->GetArrayLength(address_);
    if (length < 4) {
        return env->NewStringUTF("0.0.0.0");
    }

    const char* address_bytes = (char*)env->GetByteArrayElements(address_, NULL);
    if (NULL == address_bytes) {
        return env->NewStringUTF("0.0.0.0");
    }

    char sz[INET6_ADDRSTRLEN];
    const char* r = inet_ntop(length >= 16 ? INET6_ADDRSTRLEN : AF_INET, (struct in_addr*)address_bytes, sz, sizeof(sz)); /* in6_addr */
    env->ReleaseByteArrayElements(address_, (jbyte*)address_bytes, 0);

    if (!r) {
        return env->NewStringUTF("0.0.0.0");
    }

    return env->NewStringUTF(sz); // inet_ntoa(*(struct in_addr*)address);
}

// package: com.app.android.c
// public final class libxxx
// public native byte[] string_to_address_bytes(string address)
__LIBXXX__(jbyteArray) Java_com_app_android_c_libxxx_string_1to_1address_1bytes(JNIEnv* env, jobject this_, jstring address_) {
    __LIBXXX_MAIN__

    std::shared_ptr<app::string> address_managed = JNIENV_GetStringUTFChars(env, address_);
    uint8_t bytes[16];
    int af = 0;

    if (NULL == address_managed || address_managed->empty()) {
        *(uint32_t*)bytes = 0;
        af = AF_INET;
    }
    else {
        const char* address = NULL;
        if (NULL != address_managed) {
            address = address_managed->data();
        }

        struct sockaddr_in6 in6;
        int err = inet_pton(AF_INET6, address, &in6);
        if (err > 0) {
            af = AF_INET6;
            memcpy(bytes, &in6.sin6_addr, sizeof(bytes));
        }
        else {
            uint32_t addressV4 = inet_addr(address);
            if (addressV4 == htonl(INADDR_NONE)) {
                int b[4];
                if (sscanf(address, "%d.%d.%d.%d", &b[0], &b[1], &b[2], &b[3]) != 4) {
                    return NULL;
                }
            }

            af = AF_INET;
            *(uint32_t*)bytes = addressV4;
        }
    }

    int result_count = 
        af == AF_INET ? 
        4 : 
        16;

    jbyteArray result = env->NewByteArray(result_count);
    if (NULL == result) {
        return NULL;
    }

    jbyte* p = env->GetByteArrayElements(result, NULL);
    memcpy(p, bytes, result_count);

    env->ReleaseByteArrayElements(result, p, 0);
    return result;
}

static std::shared_ptr<xxx::string>                                         JNIENV_GetStringUTFChars(JNIEnv* env, const jstring& v) noexcept {
    std::shared_ptr<xxx::string> result;
    if (NULL != v) {
        char* s = (char*)env->GetStringUTFChars(v, NULL);
        if (NULL != s) {
            result = 
                xxx::make_shared_object<xxx::string>(s);
            env->ReleaseStringUTFChars(v, s); 
        }
    }

    return result;
}

Java:

    // Convert a string to an IP address.
    @Nullable
    public static InetAddress string_to_address(String address) {
        try {
            byte[] V = libxxx.c.string_to_address_bytes(address);
            if (V == null) {
                return null;
            } else {
                return address_of(V);
            }
        } catch (Throwable ignored) {
            return null;
        }
    }


    // Convert a bytes to an IP address string.
    public static String bytes_to_address_string(byte[] address) {
        return libxxx.c.bytes_to_address_string(address);
    }

相关推荐

  1. leetcode:反链表II 和k个链表C++实现

    2024-02-23 00:34:02       24 阅读
  2. IPv4/IPv6 播对应MAC地址

    2024-02-23 00:34:02       33 阅读
  3. IP地址学习(

    2024-02-23 00:34:02       39 阅读
  4. IP地址组成

    2024-02-23 00:34:02       17 阅读
  5. IP地址地理位置如何确定?

    2024-02-23 00:34:02       12 阅读
  6. 字符串、

    2024-02-23 00:34:02       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-23 00:34:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-23 00:34:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-23 00:34:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-23 00:34:02       20 阅读

热门阅读

  1. 去年面试的运维开发面试题二

    2024-02-23 00:34:02       35 阅读
  2. 【Kuiperinfer】笔记02 GoogleTest入门

    2024-02-23 00:34:02       29 阅读
  3. springboot+vue项目基础开发(16)主页面布局

    2024-02-23 00:34:02       26 阅读
  4. 抖音半蓝V商家电话采集软件使用教程

    2024-02-23 00:34:02       129 阅读
  5. Linux ip route命令

    2024-02-23 00:34:02       31 阅读
  6. Linux C++ 字符编码转换 GBK与UTF8互转

    2024-02-23 00:34:02       30 阅读