幾つかメソッドを追加してみた
Javaの標準にあるInetAddressクラスの中で利用できるメソッドの幾つかをAddrInfoクラスに実装してみました。
実装したのは、
- getAllByName(String hostname)
- パラメータで渡したホスト名(hostname)からIPアドレスリストを取得する。
- getByName(String hostname)
- パラメータで渡したホスト名(hostname)からIPアドレスを取得する。
- getNetworkAddress(String hostaddr, String netmask)
- パラメータで渡したホストアドレス(hostaddr)とネットマスク(netmask)からネットワークアドレスを計算する。
- isAddrInNetwork(String base, String mask, String target)
- パラメータで渡したホストアドレスorネットワークアドレス(base)とネットマスク(mask)と同じネットワークに指定したIPアドレス(target)が含まれるか計算する。
の、4つのメソッドです。
以前のAddrInfoクラスは、IfInfo用のJNIからデータを格納するためだけのクラスとして用意されていたため、時にAddrInfoクラスとしてのJNIの実装がかかれていなかったので、
AddrInfo.javaに初期化の処理を追加すると共に、次のようにスタティックメソッドを追加しました。
static { System.loadLibrary("jninet"); init(); } private static native void init(); public static native String[] getAllByName(String hostname); public static native String getByName(String hostname); public static native String getNetworkAddress(String hostaddr, String netmask); public static native boolean isAddrInNetwork(String base, String mask, String target);
何時もの様にコンパイル後、ヘッダファイルを作成。
それで前には必要なかったJNIの実装を追加します。
AddrInfo.hと
#ifndef _JNI_ADDRINFO_CALL #define _JNI_ADDRINFO_CALL #include <windows.h> #include "addrinfo.h" using namespace penguin; #include "net_AddrInfo.h" jclass str_class; /* String */ #endif // _JNI_ADDRINFO_CALL
AddrInfo.cppを
#include "jniaddrinfo.h" String jStringToString(JNIEnv *env, jstring j_string) { const jchar *words = env->GetStringChars(j_string, NULL); _bstr_t orginal = _bstr_t((wchar_t *)words); env->ReleaseStringChars(j_string, words); String c_string = String((_TCHAR *)orginal); return c_string; } JNIEXPORT void JNICALL Java_net_AddrInfo_init(JNIEnv *env, jclass cls) { jclass c = env->FindClass("java/lang/String"); str_class = (jclass)env->NewGlobalRef(c); env->DeleteLocalRef(c); } JNIEXPORT jobjectArray JNICALL Java_net_AddrInfo_getAllByName(JNIEnv *env, jclass cls, jstring hostname) { jobjectArray ai_list = NULL; String hostname_value = jStringToString(hostname); address_list list = AddrInfo::getAllByName(hostname_value); if (!list.empty()) { jsize ai_count = (jsize)list.size(); if (ai_count > 0) { ai_list = env->NewObjectArray(ai_count, str_class, NULL); for (jsize i = 0; i < ai_count; i++) { AddrInfo addr = list.at(i); String address_value = addr.getIpAddress(); _bstr_t address_str = _bstr_t((_TCHAR *)address_value.c_str()); jobject address = env->NewString((const jchar *)((wchar_t *)address_str), (jsize)address_str.length()); env->SetObjectArrayElement(ai_list, i, address); } } list.clear(); } return ai_list; } JNIEXPORT jstring JNICALL Java_net_AddrInfo_getByName(JNIEnv *env, jclass cls, jstring hostname) { jstring one_address = NULL; String hostname_value = jStringToString(hostname); String address_value = AddrInfo::getByName(hostname_value); _bstr_t address_str = _bstr_t((_TCHAR *)address_value.c_str()); one_address = env->NewString((const jchar *)((wchar_t *)address_str), (jsize)address_str.length()); return one_address; } JNIEXPORT jstring JNICALL Java_net_AddrInfo_getNetworkAddress (JNIEnv *env, jclass cls, jstring hostaddr, jstring netmask) { jstring one_address = NULL; String hostaddr_value = jStringToString(hostaddr); String netmask_value = jStringToString(netmask); String address_value = AddrInfo::getNetworkAddress(hostaddr_value, netmask_value); _bstr_t address_str = _bstr_t((_TCHAR *)address_value.c_str()); one_address = env->NewString((const jchar *)((wchar_t *)address_str), (jsize)address_str.length()); return one_address; } JNIEXPORT jboolean JNICALL Java_net_AddrInfo_isAddrInNetwork(JNIEnv *env, jclass cls, jstring base, jstring mask, jstring target) { String base_value = jStringToString(base); String mask_value = jStringToString(mask); String target_value = jStringToString(target); return (jboolean)AddrInfo::isAddrInNetwork(base_value, mask_value, target_value); }
実装しました。
後はJavaからのテストで
String[] addrs = AddrInfo.getAllByName("www.google.co.jp"); for (int i = 0; i < addrs.length; i++) { System.out.println("Google addrs "+i+" = "+addrs[i]); } String netAddr = AddrInfo.getNetworkAddress("172.16.255.1", "255.255.255.0"); System.out.println("Network address = "+netAddr); if (AddrInfo.isAddrInNetwork("172.16.255.0", "255.255.255.0", "172.16.255.1")) System.out.println("Network address is local"); else System.out.println("Network address is not local");
で確認してOkでした。