📄 natplainsocketimplwin32.cc
字号:
jbyte *bytes = elements (b) + offset; int written = 0; while (len > 0) { int r = ::send (this$0->native_fd, (char*) bytes, len, 0); if (r == -1) { DWORD dwErr = WSAGetLastError(); // Reset and ignore our thread's interrupted flag. ::java::lang::Thread::interrupted(); // Some errors should not cause exceptions. if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET && dwErr != WSAENOTSOCK) _Jv_ThrowIOException (); break; } written += r; len -= r; bytes += r; }}voidgnu::java::net::PlainSocketImpl::sendUrgentData (jint){ throw new ::java::net::SocketException (JvNewStringLatin1 ( "PlainSocketImpl: sending of urgent data not supported by this socket"));}// read() helperstatic jintdoRead(int native_fd, void* buf, int count, int timeout){ int r = 0; DWORD dwErrorCode = 0; // we are forced to declare this here because // a call to Thread::interrupted() blanks out // WSAGetLastError(). // FIXME: we unconditionally set SO_RCVTIMEO here // because we can't detect whether someone has // gone from a non-zero to zero timeout. What we'd // really need is a member state variable in addition // to timeout int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)); if (nRet != NO_ERROR) { dwErrorCode = WSAGetLastError (); goto error; } r = ::recv (native_fd, (char*) buf, count, 0); if (r == 0) return -1; dwErrorCode = WSAGetLastError (); // save WSAGetLastError() before calling Thread.interrupted() // Reset and ignore our thread's interrupted flag. ::java::lang::Thread::interrupted(); if (r == -1) {error: // Some errors cause us to return end of stream... if (dwErrorCode == WSAENOTCONN) return -1; // Other errors need to be signalled. if (dwErrorCode == WSAETIMEDOUT) throw new ::java::net::SocketTimeoutException (JvNewStringUTF ("Read timed out") ); else _Jv_ThrowIOException (dwErrorCode); } return r;}// Read a single byte from the socket.jintgnu::java::net::PlainSocketImpl$SocketInputStream::read(void){ jbyte b; doRead(this$0->native_fd, &b, 1, this$0->timeout); return b & 0xFF;}// Read count bytes into the buffer, starting at offset.jintgnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer, jint offset, jint count){ // If zero bytes were requested, short circuit so that recv // doesn't signal EOF. if (count == 0) return 0; 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; // Read the socket. return doRead(this$0->native_fd, bytes, count, this$0->timeout);}// How many bytes are available?jintgnu::java::net::PlainSocketImpl::available(void){ unsigned long num = 0; if (::ioctlsocket (native_fd, FIONREAD, &num) == SOCKET_ERROR) _Jv_ThrowIOException (); return (jint) num;}voidgnu::java::net::PlainSocketImpl::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); 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_ : if (::setsockopt (native_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &val, val_len) == SOCKET_ERROR) goto error; return; case _Jv_SO_KEEPALIVE_ : if (::setsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, val_len) == SOCKET_ERROR) 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 (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val, val_len) == SOCKET_ERROR) goto error; break; case _Jv_SO_LINGER_ : struct linger l_val; l_val.l_onoff = (val != -1); l_val.l_linger = val; if (::setsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val, sizeof(l_val)) == SOCKET_ERROR) goto error; return; case _Jv_SO_SNDBUF_ : case _Jv_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) == SOCKET_ERROR) goto error; 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 (native_fd, SOL_SOCKET, IP_TOS, (char *) &val, val_len) == SOCKET_ERROR) 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 : WSASetLastError (WSAENOPROTOOPT); }error: _Jv_ThrowSocketException ();}::java::lang::Object *gnu::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) { case _Jv_TCP_NODELAY_ : if (::getsockopt (native_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &val, &val_len) == SOCKET_ERROR) goto error; else return new ::java::lang::Boolean (val != 0); break; case _Jv_SO_LINGER_ : if (::getsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val, &l_val_len) == SOCKET_ERROR) goto error; if (l_val.l_onoff) return new ::java::lang::Integer (l_val.l_linger); else return new ::java::lang::Boolean ((jboolean)false); break; case _Jv_SO_KEEPALIVE_ : if (::getsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, &val_len) == SOCKET_ERROR) goto error; else return new ::java::lang::Boolean (val != 0); case _Jv_SO_BROADCAST_ : if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val, &val_len) == SOCKET_ERROR) goto error; return new ::java::lang::Boolean ((jboolean)val); case _Jv_SO_OOBINLINE_ : if (::getsockopt (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val, &val_len) == SOCKET_ERROR) goto error; return new ::java::lang::Boolean ((jboolean)val); case _Jv_SO_RCVBUF_ : case _Jv_SO_SNDBUF_ : int opt; optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, &val_len) == SOCKET_ERROR) goto error; else return new ::java::lang::Integer (val); break; case _Jv_SO_BINDADDR_: // cache the local address if (localAddress == NULL) { jbyteArray laddr; if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) == SOCKET_ERROR) 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 (native_fd, SOL_SOCKET, IP_TOS, (char *) &val, &val_len) == SOCKET_ERROR) 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 : WSASetLastError (WSAENOPROTOOPT); }error: _Jv_ThrowSocketException (); return 0; // we should never get here}voidgnu::java::net::PlainSocketImpl::shutdownInput (void){ if (::shutdown (native_fd, 0)) _Jv_ThrowSocketException ();}voidgnu::java::net::PlainSocketImpl::shutdownOutput (void){ if (::shutdown (native_fd, 1)) _Jv_ThrowSocketException ();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -