- 論壇徽章:
- 0
|
本帖最后由 wliang511 于 2011-11-09 23:10 編輯
糾結(jié)了很多天了,跟一個(gè)問(wèn)題跟到這里,但是覺(jué)得google又不可能犯這么低級(jí)的錯(cuò)誤...請(qǐng)大家指出我愚蠢的地方吧
android 2.2 froyo版本
在froyo\dalvik\libcore\luni\src\main\native\org_apache_harmony_luni_platform_OSNetworkSystem.cpp中(這里只貼出相關(guān)的2個(gè)case語(yǔ)句):
我們暫時(shí)只看IPV4的部分:
在case JAVASOCKOPT_IP_MULTICAST_IF中,getsockopt(...,....,...,&sockval,...)語(yǔ)句之后有sockval.ss_family的引用,因此這個(gè)sockval至少是
一個(gè)大小大于4個(gè)字節(jié)的結(jié)構(gòu)體,從緊接的代碼socketAddressToInetAddress()中可以看出內(nèi)核應(yīng)該返回的sockval為struct sockaddr_in類型
在case JAVASOCKOPT_IP_MULTICAST_IF2,AF_INET時(shí),很明顯getsockopt(...,....,...,&sockval,...)返回的sockval類型必須是struct ip_mreqn類型
但是從內(nèi)核代碼\kernel\net\ipv4\ip_sockglue.c中
case IP_MULTICAST_IF中可以看到,getsockopt明明只支持返回類型為struct in_addr的結(jié)構(gòu)體
這,問(wèn)題究竟在哪里呢?
froyo\dalvik\libcore\luni\src\main\native\org_apache_harmony_luni_platform_OSNetworkSystem.cpp:
- static jobject osNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jint anOption) {
- // LOGD("ENTER getSocketOptionImpl");
- int intValue = 0;
- socklen_t intSize = sizeof(int);
- int result;
- struct sockaddr_storage sockVal;
- socklen_t sockSize = sizeof(sockVal);
- int handle;
- if (!jniGetFd(env, fileDescriptor, handle)) {
- return 0;
- }
- switch ((int) anOption & 0xffff) {
- case JAVASOCKOPT_IP_MULTICAST_IF: {
- if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
- return NULL;
- }
- result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF,
- &sockVal, &sockSize);
- if (result == -1) {
- jniThrowSocketException(env, errno);
- return NULL;
- }
- if (sockVal.ss_family != AF_INET) {
- // Java expects an AF_INET INADDR_ANY, but Linux just returns AF_UNSPEC.
- jbyteArray inAddrAny = env->NewByteArray(4); // { 0, 0, 0, 0 }
- return byteArrayToInetAddress(env, inAddrAny);
- }
- return socketAddressToInetAddress(env, &sockVal);
- }
- case JAVASOCKOPT_IP_MULTICAST_IF2: {
- if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
- return NULL;
- }
- struct ip_mreqn multicastRequest;
- int interfaceIndex = 0;
- socklen_t optionLength;
- int addressFamily = getSocketAddressFamily(handle);
- switch (addressFamily) {
- case AF_INET:
- optionLength = sizeof(multicastRequest);
- result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF,
- &multicastRequest, &optionLength);
- if (result == 0)
- interfaceIndex = multicastRequest.imr_ifindex;
- break;
- case AF_INET6:
- optionLength = sizeof(interfaceIndex);
- result = getsockopt(handle, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- &interfaceIndex, &optionLength);
- break;
- default:
- jniThrowSocketException(env, EAFNOSUPPORT);
- return NULL;
- }
- if (0 != result) {
- jniThrowSocketException(env, errno);
- return NULL;
- }
- return newJavaLangInteger(env, interfaceIndex);
- }
- }
- }
復(fù)制代碼 但是從內(nèi)核代碼\kernel\net\ipv4\ip_sockglue.c中
case IP_MULTICAST_IF中可以看到,getsockopt明明只支持返回類型為struct in_addr的結(jié)構(gòu)體
kernel\net\ipv4\ip_sockglue.c:
- /*
- * Get the options. Note for future reference. The GET of IP options gets the
- * _received_ ones. The set sets the _sent_ ones.
- */
- static int do_ip_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
- {
- struct inet_sock *inet = inet_sk(sk);
- int val;
- int len;
- if (level != SOL_IP)
- return -EOPNOTSUPP;
- if (ip_mroute_opt(optname))
- return ip_mroute_getsockopt(sk,optname,optval,optlen);
- if (get_user(len,optlen))
- return -EFAULT;
- if (len < 0)
- return -EINVAL;
- lock_sock(sk);
- switch (optname) {
- case IP_MULTICAST_IF:
- {
- struct in_addr addr;
- len = min_t(unsigned int, len, sizeof(struct in_addr));
- addr.s_addr = inet->mc_addr;
- release_sock(sk);
- if (put_user(len, optlen))
- return -EFAULT;
- if (copy_to_user(optval, &addr, len))
- return -EFAULT;
- return 0;
- }
- }
- }
復(fù)制代碼 |
|