📄 natplaindatagramsocketimpl.cc
字号:
throw new java::io::IOException (JvNewStringUTF (strerr));}voidjava::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p){ // FIXME: Deal with Multicast and if the socket is connected. union SockAddr u; socklen_t addrlen = sizeof(u); jbyte *dbytes = elements (p->getData()); ssize_t retlen = 0;// FIXME: implement timeout support for Win32#ifndef WIN32 // Do timeouts via select since SO_RCVTIMEO is not always available. if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) { fd_set rset; struct timeval tv; FD_ZERO(&rset); FD_SET(fnum, &rset); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; int retval; if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) goto error; else if (retval == 0) throw new java::io::InterruptedIOException (); }#endif /* WIN32 */ retlen = ::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u, &addrlen); if (retlen < 0) goto error; // FIXME: Deal with Multicast addressing and if the socket is connected. jbyteArray raddr; jint rport; if (u.address.sin_family == AF_INET) { raddr = JvNewByteArray (4); memcpy (elements (raddr), &u.address.sin_addr, 4); rport = ntohs (u.address.sin_port); }#ifdef HAVE_INET6 else if (u.address.sin_family == AF_INET6) { raddr = JvNewByteArray (16); memcpy (elements (raddr), &u.address6.sin6_addr, 16); rport = ntohs (u.address6.sin6_port); }#endif else throw new java::net::SocketException (JvNewStringUTF ("invalid family")); p->setAddress (new InetAddress (raddr, NULL)); p->setPort (rport); p->setLength ((jint) retlen); return; error: char* strerr = strerror (errno); if (errno == ECONNREFUSED) throw new PortUnreachableException (JvNewStringUTF (strerr)); throw new java::io::IOException (JvNewStringUTF (strerr));}voidjava::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl){ // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4. char val = (char) ttl; socklen_t val_len = sizeof(val); if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0) return; char* strerr = strerror (errno); throw new java::io::IOException (JvNewStringUTF (strerr));}jintjava::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 (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0) return ((int) val) & 0xFF; char* strerr = strerror (errno); throw new java::io::IOException (JvNewStringUTF (strerr));}voidjava::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr, java::net::NetworkInterface *, jboolean join){ // FIXME: implement use of NetworkInterface union McastReq u; jbyteArray haddress = inetaddr->addr; jbyte *bytes = elements (haddress); 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 (fnum, level, opname, ptr, len) == 0) return; char* strerr = strerror (errno); throw new java::io::IOException (JvNewStringUTF (strerr));}voidjava::net::PlainDatagramSocketImpl::setOption (jint optID, java::lang::Object *value){ int val; socklen_t val_len = sizeof (val); if (fnum < 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 (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, val_len) != 0) goto error; break; case _Jv_SO_OOBINLINE_ : throw new java::net::SocketException ( JvNewStringUTF ("SO_OOBINLINE: not valid for UDP")); break; 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 (fnum, 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 (fnum, 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 (fnum, 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")); break; case _Jv_IP_MULTICAST_LOOP_ : throw new java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented")); break; case _Jv_IP_TOS_ : if (::setsockopt (fnum, 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 *java::net::PlainDatagramSocketImpl::getOption (jint optID){ int val; socklen_t val_len = sizeof(val); union SockAddr u; socklen_t addrlen = sizeof(u); 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 (fnum, 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 (fnum, 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) { jbyteArray laddr; if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) goto error; 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")); localAddress = new java::net::InetAddress (laddr, NULL); } return localAddress; break; case _Jv_SO_REUSEADDR_ :#if defined(SO_REUSEADDR) if (::getsockopt (fnum, 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 (fnum, 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_ : if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val, &val_len) != 0) goto error; return new java::lang::Boolean (val != 0); case _Jv_IP_TOS_ : if (::getsockopt (fnum, 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));}#endif /* DISABLE_JAVA_NET */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -