📄 natplainsocketimpl.cc
字号:
{ java::io::InterruptedIOException *iioe = new java::io::InterruptedIOException (JvNewStringLatin1 (strerror (errno))); iioe->bytesTransferred = written; throw iioe; } // Some errors should not cause exceptions. if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) throw new java::io::IOException (JvNewStringUTF (strerror (errno))); break; } written += r; len -= r; bytes += r; }}voidjava::net::PlainSocketImpl::sendUrgentData (jint){ throw new SocketException (JvNewStringLatin1 ( "PlainSocketImpl: sending of urgent data not supported by this socket"));}// Read a single byte from the socket.jintjava::net::PlainSocketImpl::read(void){ jbyte b;// FIXME: implement timeout support for Win32#ifndef WIN32 // Do timeouts via select. if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) { // Create the file descriptor set. fd_set read_fds; FD_ZERO (&read_fds); FD_SET (fnum,&read_fds); // Create the timeout struct based on our internal timeout value. struct timeval timeout_value; timeout_value.tv_sec = timeout / 1000; timeout_value.tv_usec = (timeout % 1000) * 1000; // Select on the fds. int sel_retval = _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value); // If select returns 0 we've waited without getting data... // that means we've timed out. if (sel_retval == 0) throw new java::io::InterruptedIOException (JvNewStringUTF ("read timed out") ); // If select returns ok we know we either got signalled or read some data... // either way we need to try to read. }#endif /* WIN32 */ int r = _Jv_read (fnum, &b, 1); if (r == 0) return -1; if (java::lang::Thread::interrupted()) { java::io::InterruptedIOException *iioe = new java::io::InterruptedIOException (JvNewStringUTF("read interrupted")); iioe->bytesTransferred = r == -1 ? 0 : r; throw iioe; } else if (r == -1) { // Some errors cause us to return end of stream... if (errno == ENOTCONN) return -1; // Other errors need to be signalled. throw new java::io::IOException (JvNewStringUTF (strerror (errno))); } return b & 0xFF;}// Read count bytes into the buffer, starting at offset.jintjava::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count){ if (! buffer) throw new java::lang::NullPointerException; jsize bsize = JvGetArrayLength (buffer); if (offset < 0 || count < 0 || offset + count > bsize) throw new java::lang::ArrayIndexOutOfBoundsException; jbyte *bytes = elements (buffer) + offset;// FIXME: implement timeout support for Win32#ifndef WIN32 // Do timeouts via select. if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) { // Create the file descriptor set. fd_set read_fds; FD_ZERO (&read_fds); FD_SET (fnum, &read_fds); // Create the timeout struct based on our internal timeout value. struct timeval timeout_value; timeout_value.tv_sec = timeout / 1000; timeout_value.tv_usec =(timeout % 1000) * 1000; // Select on the fds. int sel_retval = _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value); // We're only interested in the 0 return. // error returns still require us to try to read // the socket to see what happened. if (sel_retval == 0) { java::io::InterruptedIOException *iioe = new java::io::InterruptedIOException (JvNewStringUTF ("read interrupted")); iioe->bytesTransferred = 0; throw iioe; } }#endif // Read the socket. int r = ::recv (fnum, (char *) bytes, count, 0); if (r == 0) return -1; if (java::lang::Thread::interrupted()) { java::io::InterruptedIOException *iioe = new java::io::InterruptedIOException (JvNewStringUTF ("read interrupted")); iioe->bytesTransferred = r == -1 ? 0 : r; throw iioe; } else if (r == -1) { // Some errors cause us to return end of stream... if (errno == ENOTCONN) return -1; // Other errors need to be signalled. throw new java::io::IOException (JvNewStringUTF (strerror (errno))); } return r;}// How many bytes are available?jintjava::net::PlainSocketImpl::available(void){#if defined(FIONREAD) || defined(HAVE_SELECT) long num = 0; int r = 0; bool num_set = false;#if defined(FIONREAD) r = ::ioctl (fnum, FIONREAD, &num); if (r == -1 && errno == ENOTTY) { // If the ioctl doesn't work, we don't care. r = 0; num = 0; } else num_set = true;#elif defined(HAVE_SELECT) if (fnum < 0) { errno = EBADF; r = -1; }#endif if (r == -1) { posix_error: throw new java::io::IOException(JvNewStringUTF(strerror(errno))); } // If we didn't get anything we can use select.#if defined(HAVE_SELECT) if (! num_set) if (! num_set && fnum >= 0 && fnum < FD_SETSIZE) { fd_set rd; FD_ZERO (&rd); FD_SET (fnum, &rd); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; r = _Jv_select (fnum + 1, &rd, NULL, NULL, &tv); if(r == -1) goto posix_error; num = r == 0 ? 0 : 1; }#endif /* HAVE_SELECT */ return (jint) num;#else throw new java::io::IOException (JvNewStringUTF ("unimplemented"));#endif}voidjava::net::PlainSocketImpl::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); if (boolobj->booleanValue()) val = 1; else { if (optID == _Jv_SO_LINGER_) val = -1; else val = 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 { throw new java::lang::IllegalArgumentException ( JvNewStringLatin1 ("`value' must be Boolean or Integer")); } switch (optID) { case _Jv_TCP_NODELAY_ :#ifdef TCP_NODELAY if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, val_len) != 0) goto error;#else throw new java::lang::InternalError (JvNewStringUTF ("TCP_NODELAY not supported"));#endif /* TCP_NODELAY */ return; case _Jv_SO_KEEPALIVE_ : if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, val_len) != 0) goto error; break; case _Jv_SO_BROADCAST_ : throw new java::net::SocketException (JvNewStringUTF ("SO_BROADCAST not valid for TCP")); break; case _Jv_SO_OOBINLINE_ : if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, val_len) != 0) goto error; break; case _Jv_SO_LINGER_ :#ifdef SO_LINGER struct linger l_val; l_val.l_onoff = (val != -1); l_val.l_linger = val; if (::setsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, sizeof(l_val)) != 0) goto error; #else throw new java::lang::InternalError ( JvNewStringUTF ("SO_LINGER not supported"));#endif /* SO_LINGER */ 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 (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_BINDADDR_ : throw new java::net::SocketException ( JvNewStringUTF ("SO_BINDADDR: read only option")); return; case _Jv_IP_MULTICAST_IF_ : throw new java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); return; case _Jv_IP_MULTICAST_IF2_ : throw new java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); break; case _Jv_IP_MULTICAST_LOOP_ : throw new java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); break; case _Jv_IP_TOS_ : if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, val_len) != 0) goto error; break; case _Jv_SO_REUSEADDR_ : throw new java::net::SocketException ( JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); 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::PlainSocketImpl::getOption (jint optID){ int val; socklen_t val_len = sizeof(val); union SockAddr u; socklen_t addrlen = sizeof(u); struct linger l_val; socklen_t l_val_len = sizeof(l_val); switch (optID) {#ifdef TCP_NODELAY case _Jv_TCP_NODELAY_ : if (::getsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, &val_len) != 0) goto error; else return new java::lang::Boolean (val != 0);#else throw new java::lang::InternalError (JvNewStringUTF ("TCP_NODELAY not supported"));#endif break; case _Jv_SO_LINGER_ :#ifdef SO_LINGER if (::getsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, &l_val_len) != 0) goto error; if (l_val.l_onoff) return new java::lang::Integer (l_val.l_linger); else return new java::lang::Boolean ((jboolean)false);#else throw new java::lang::InternalError (JvNewStringUTF ("SO_LINGER not supported"));#endif break; case _Jv_SO_KEEPALIVE_ : if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, &val_len) != 0) goto error; else return new java::lang::Boolean (val != 0); case _Jv_SO_BROADCAST_ : if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, &val_len) != 0) goto error; return new java::lang::Boolean ((jboolean)val); case _Jv_SO_OOBINLINE_ : if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, &val_len) != 0) goto error; return new java::lang::Boolean ((jboolean)val); 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_IP_MULTICAST_IF_ : throw new java::net::SocketException (JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); break; case _Jv_IP_MULTICAST_IF2_ : throw new java::net::SocketException (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); break; case _Jv_IP_MULTICAST_LOOP_ : throw new java::net::SocketException (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); break; case _Jv_IP_TOS_ : if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, &val_len) != 0) goto error; return new java::lang::Integer (val); break; case _Jv_SO_REUSEADDR_ : throw new java::net::SocketException (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); break; case _Jv_SO_TIMEOUT_ : return new java::lang::Integer (timeout); break; default : errno = ENOPROTOOPT; } error: char* strerr = strerror (errno); throw new java::net::SocketException (JvNewStringUTF (strerr));}voidjava::net::PlainSocketImpl::shutdownInput (void){ if (::shutdown (fnum, 0)) throw new SocketException (JvNewStringUTF (strerror (errno)));}voidjava::net::PlainSocketImpl::shutdownOutput (void){ if (::shutdown (fnum, 1)) throw new SocketException (JvNewStringUTF (strerror (errno)));}#endif /* DISABLE_JAVA_NET */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -