📄 natplaindatagramsocketimplposix.cc
字号:
char* strerr = strerror (errno); throw new ::java::io::IOException (JvNewStringUTF (strerr));}jintgnu::java::net::PlainDatagramSocketImpl::getTimeToLive (){ // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4. char val; socklen_t val_len = sizeof(val); if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0) return ((int) val) & 0xFF; char* strerr = strerror (errno); throw new ::java::io::IOException (JvNewStringUTF (strerr));}voidgnu::java::net::PlainDatagramSocketImpl::mcastGrp (::java::net::InetAddress *inetaddr, ::java::net::NetworkInterface *, jboolean join){ // FIXME: implement use of NetworkInterface jbyteArray haddress = inetaddr->addr;#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IPV6_MREQ union McastReq u; jbyte *bytes = elements (haddress);#endif int len = haddress->length; int level, opname; const char *ptr; if (0) ;#if HAVE_STRUCT_IP_MREQ else if (len == 4) { level = IPPROTO_IP; opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; memcpy (&u.mreq.imr_multiaddr, bytes, len); // FIXME: If a non-default interface is set, use it; see Stevens p. 501. // Maybe not, see note in last paragraph at bottom of Stevens p. 497. u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); len = sizeof (struct ip_mreq); ptr = (const char *) &u.mreq; }#endif#if HAVE_STRUCT_IPV6_MREQ else if (len == 16) { level = IPPROTO_IPV6; /* Prefer new RFC 2553 names. */#ifndef IPV6_JOIN_GROUP#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP#endif#ifndef IPV6_LEAVE_GROUP#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP#endif opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP; memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len); // FIXME: If a non-default interface is set, use it; see Stevens p. 501. // Maybe not, see note in last paragraph at bottom of Stevens p. 497. u.mreq6.ipv6mr_interface = 0; len = sizeof (struct ipv6_mreq); ptr = (const char *) &u.mreq6; }#endif else throw new ::java::net::SocketException (JvNewStringUTF ("invalid length")); if (::setsockopt (native_fd, level, opname, ptr, len) == 0) return; char* strerr = strerror (errno); throw new ::java::io::IOException (JvNewStringUTF (strerr));}// Helper function to get the InetAddress for a given socket (file// descriptor).static ::java::net::InetAddress *getLocalAddress (int native_fd){ jbyteArray laddr; union SockAddr u; socklen_t addrlen = sizeof(u); if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != 0) { char* strerr = strerror (errno); throw new ::java::net::SocketException (JvNewStringUTF (strerr)); } if (u.address.sin_family == AF_INET) { laddr = JvNewByteArray (4); memcpy (elements (laddr), &u.address.sin_addr, 4); }#ifdef HAVE_INET6 else if (u.address.sin_family == AF_INET6) { laddr = JvNewByteArray (16); memcpy (elements (laddr), &u.address6.sin6_addr, 16); }#endif else throw new ::java::net::SocketException (JvNewStringUTF ("invalid family")); return new ::java::net::InetAddress (laddr, NULL);}voidgnu::java::net::PlainDatagramSocketImpl::setOption (jint optID, ::java::lang::Object *value){ int val; socklen_t val_len = sizeof (val); if (native_fd < 0) throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed")); if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$)) { ::java::lang::Boolean *boolobj = static_cast< ::java::lang::Boolean *> (value); val = boolobj->booleanValue() ? 1 : 0; } else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$)) { ::java::lang::Integer *intobj = static_cast< ::java::lang::Integer *> (value); val = (int) intobj->intValue(); } // Else assume value to be an InetAddress for use with IP_MULTICAST_IF. switch (optID) { case _Jv_TCP_NODELAY_ : throw new ::java::net::SocketException ( JvNewStringUTF ("TCP_NODELAY not valid for UDP")); return; case _Jv_SO_LINGER_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_LINGER not valid for UDP")); return; case _Jv_SO_KEEPALIVE_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); return; case _Jv_SO_BROADCAST_ : if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val, val_len) != 0) goto error; return; case _Jv_SO_OOBINLINE_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_OOBINLINE: not valid for UDP")); return; case _Jv_SO_SNDBUF_ : case _Jv_SO_RCVBUF_ :#if defined(SO_SNDBUF) && defined(SO_RCVBUF) int opt; optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; if (::setsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, val_len) != 0) goto error; #else throw new ::java::lang::InternalError ( JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));#endif return; case _Jv_SO_REUSEADDR_ :#if defined(SO_REUSEADDR) if (::setsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, val_len) != 0) goto error;#else throw new ::java::lang::InternalError ( JvNewStringUTF ("SO_REUSEADDR not supported"));#endif return; case _Jv_SO_BINDADDR_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_BINDADDR: read only option")); return; case _Jv_IP_MULTICAST_IF_ : union InAddr u; jbyteArray haddress; jbyte *bytes; int len; int level, opname; const char *ptr; haddress = ((::java::net::InetAddress *) value)->addr; bytes = elements (haddress); len = haddress->length; if (len == 4) { level = IPPROTO_IP; opname = IP_MULTICAST_IF; memcpy (&u.addr, bytes, len); len = sizeof (struct in_addr); ptr = (const char *) &u.addr; }// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF) else if (len == 16) { level = IPPROTO_IPV6; opname = IPV6_MULTICAST_IF; memcpy (&u.addr6, bytes, len); len = sizeof (struct in6_addr); ptr = (const char *) &u.addr6; }#endif else throw new ::java::net::SocketException (JvNewStringUTF ("invalid length")); if (::setsockopt (native_fd, level, opname, ptr, len) != 0) goto error; return; case _Jv_IP_MULTICAST_IF2_ : throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); return; case _Jv_IP_MULTICAST_LOOP_ : // cache the local address if (localAddress == NULL) localAddress = getLocalAddress (native_fd); len = localAddress->addr->length; if (len == 4) { level = IPPROTO_IP; opname = IP_MULTICAST_LOOP; }#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP) else if (len == 16) { level = IPPROTO_IPV6; opname = IPV6_MULTICAST_LOOP; }#endif else throw new ::java::net::SocketException (JvNewStringUTF ("invalid address length")); if (::setsockopt (native_fd, level, opname, (char *) &val, val_len) != 0) goto error; return; case _Jv_IP_TOS_ : if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val, val_len) != 0) goto error; return; case _Jv_SO_TIMEOUT_ : timeout = val; return; default : errno = ENOPROTOOPT; } error: char* strerr = strerror (errno); throw new ::java::net::SocketException (JvNewStringUTF (strerr));}::java::lang::Object *gnu::java::net::PlainDatagramSocketImpl::getOption (jint optID){ int val; socklen_t val_len = sizeof(val); int level, opname; switch (optID) { case _Jv_TCP_NODELAY_ : throw new ::java::net::SocketException ( JvNewStringUTF ("TCP_NODELAY not valid for UDP")); break; case _Jv_SO_LINGER_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_LINGER not valid for UDP")); break; case _Jv_SO_KEEPALIVE_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); break; case _Jv_SO_BROADCAST_ : if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val, &val_len) != 0) goto error; return new ::java::lang::Boolean (val != 0); case _Jv_SO_OOBINLINE_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_OOBINLINE not valid for UDP")); break; case _Jv_SO_RCVBUF_ : case _Jv_SO_SNDBUF_ :#if defined(SO_SNDBUF) && defined(SO_RCVBUF) int opt; optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, &val_len) != 0) goto error; else return new ::java::lang::Integer (val);#else throw new ::java::lang::InternalError ( JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));#endif break; case _Jv_SO_BINDADDR_: // cache the local address if (localAddress == NULL) localAddress = getLocalAddress (native_fd); return localAddress; break; case _Jv_SO_REUSEADDR_ :#if defined(SO_REUSEADDR) if (::getsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, &val_len) != 0) goto error; return new ::java::lang::Boolean (val != 0);#else throw new ::java::lang::InternalError ( JvNewStringUTF ("SO_REUSEADDR not supported"));#endif break; case _Jv_IP_MULTICAST_IF_ :#ifdef HAVE_INET_NTOA struct in_addr inaddr; socklen_t inaddr_len; char *bytes; inaddr_len = sizeof(inaddr); if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr, &inaddr_len) != 0) goto error; bytes = inet_ntoa (inaddr); return ::java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));#else throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));#endif break; case _Jv_SO_TIMEOUT_ : return new ::java::lang::Integer (timeout); break; case _Jv_IP_MULTICAST_IF2_ : throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); break; case _Jv_IP_MULTICAST_LOOP_ : // cache the local address localAddress = getLocalAddress (native_fd); if (localAddress->addr->length == 4) { level = IPPROTO_IP; opname = IP_MULTICAST_LOOP; }#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP) else if (localAddress->addr->length == 16) { level = IPPROTO_IPV6; opname = IPV6_MULTICAST_LOOP; }#endif else throw new ::java::net::SocketException (JvNewStringUTF ("invalid address length")); if (::getsockopt (native_fd, level, opname, (char *) &val, &val_len) != 0) goto error; return new ::java::lang::Boolean (val != 0); case _Jv_IP_TOS_ : if (::getsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val, &val_len) != 0) goto error; return new ::java::lang::Integer (val); default : errno = ENOPROTOOPT; } error: char* strerr = strerror (errno); throw new ::java::net::SocketException (JvNewStringUTF (strerr));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -