📄 javanet.c
字号:
* port - The port number to send to (may be 0) */void_javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len, int addr, int port){#ifndef WITHOUT_NETWORK int fd; jbyte *p; int bytes_sent; /* Get the real file descriptor */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_sendto(): no native file descriptor"); return; } /* Get a pointer to the buffer */ p = (*env)->GetByteArrayElements (env, buf, 0); if (p == NULL) return; /* We must send all the data, so repeat till done. */ while (len > 0) { /* Send the data */ if (addr == 0) { DBG ("_javanet_sendto(): Sending....\n"); TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent); } else { DBG ("_javanet_sendto(): Sending....\n"); TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT (fd, p + offset, len, addr, port, bytes_sent); } if (bytes_sent < 0) { if (TARGET_NATIVE_LAST_ERROR () != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); break; } } else { len -= bytes_sent; addr += bytes_sent; } } (*env)->ReleaseByteArrayElements (env, buf, p, 0);#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Sets the specified option for a socket */void_javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val){#ifndef WITHOUT_NETWORK int fd; int optval; jclass cls; jmethodID mid; int address; int result; /* Get the real file descriptor */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option(): no native file descriptor"); return; } /* We need a class object for all cases below */ cls = (*env)->GetObjectClass (env, val); if (cls == NULL) return; /* Process the option request */ result = TARGET_NATIVE_ERROR; switch (option_id) { /* TCP_NODELAY case. val is a Boolean that tells us what to do */ case SOCKOPT_TCP_NODELAY: mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); if (mid == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } /* Should be a 0 or a 1 */ optval = (*env)->CallBooleanMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY (fd, optval, result); break; /* SO_LINGER case. If val is a boolean, then it will always be set to false indicating disable linger, otherwise it will be an integer that contains the linger value */ case SOCKOPT_SO_LINGER: mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); if (mid) { /* We are disabling linger */ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 1, 0, result); } else { /* Clear exception if thrown for failure to do method lookup above */ if ((*env)->ExceptionOccurred (env)) (*env)->ExceptionClear (env); mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); if (mid == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } optval = (*env)->CallIntMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 0, optval, result); } break; /* SO_TIMEOUT case. Val will be an integer with the new value */ /* Not writable on Linux */ case SOCKOPT_SO_TIMEOUT:#ifdef SO_TIMEOUT mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); if (mid == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } optval = (*env)->CallIntMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (fd, optval, result);#else result = TARGET_NATIVE_OK;#endif break; case SOCKOPT_SO_SNDBUF: case SOCKOPT_SO_RCVBUF: mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); if (mid == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } optval = (*env)->CallIntMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; if (option_id == SOCKOPT_SO_SNDBUF) TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF (fd, optval, result); else TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF (fd, optval, result); break; /* TTL case. Val with be an Integer with the new time to live value */ case SOCKOPT_IP_TTL: mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); if (!mid) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } optval = (*env)->CallIntMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL (fd, optval, result); break; /* Multicast Interface case - val is InetAddress object */ case SOCKOPT_IP_MULTICAST_IF: address = _javanet_get_netaddr (env, val); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF (fd, address, result); break; case SOCKOPT_SO_REUSEADDR: mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); if (mid == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } /* Should be a 0 or a 1 */ optval = (*env)->CallBooleanMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS (fd, optval, result); break; case SOCKOPT_SO_KEEPALIVE: mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); if (mid == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_set_option()"); return; } /* Should be a 0 or a 1 */ optval = (*env)->CallBooleanMethod (env, val, mid); if ((*env)->ExceptionOccurred (env)) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE (fd, optval, result); break; case SOCKOPT_SO_BINDADDR: JCL_ThrowException (env, SOCKET_EXCEPTION, "This option cannot be set"); break; default: JCL_ThrowException (env, SOCKET_EXCEPTION, "Unrecognized option"); return; } /* Check to see if above operations succeeded */ if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return; }#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Retrieves the specified option values for a socket */jobject_javanet_get_option (JNIEnv * env, jobject this, jint option_id){#ifndef WITHOUT_NETWORK int fd; int flag, optval; int address; int result; /* Get the real file descriptor */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { JCL_ThrowException (env, SOCKET_EXCEPTION, "Internal error: _javanet_get_option(): no native file descriptor"); return (0); } /* Process the option requested */ switch (option_id) { /* TCP_NODELAY case. Return a Boolean indicating on or off */ case SOCKOPT_TCP_NODELAY: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY (fd, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } if (optval) return (_javanet_create_boolean (env, JNI_TRUE)); else return (_javanet_create_boolean (env, JNI_FALSE)); break; /* SO_LINGER case. If disabled, return a Boolean object that represents false, else return an Integer that is the value of SO_LINGER */ case SOCKOPT_SO_LINGER: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER (fd, flag, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } if (optval) return (_javanet_create_integer (env, JNI_TRUE)); else return (_javanet_create_boolean (env, JNI_FALSE)); break; /* SO_TIMEOUT case. Return an Integer object with the timeout value */ case SOCKOPT_SO_TIMEOUT:#ifdef SO_TIMEOUT TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT (fd, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } return (_javanet_create_integer (env, optval));#else JCL_ThrowException (env, SOCKET_EXCEPTION, "SO_TIMEOUT not supported on this platform"); return (0);#endif /* not SO_TIMEOUT */ break; case SOCKOPT_SO_SNDBUF: case SOCKOPT_SO_RCVBUF: if (option_id == SOCKOPT_SO_SNDBUF) TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF (fd, optval, result); else TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF (fd, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } return (_javanet_create_integer (env, optval)); break; /* The TTL case. Return an Integer with the Time to Live value */ case SOCKOPT_IP_TTL: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL (fd, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } return (_javanet_create_integer (env, optval)); break; /* Multicast interface case */ case SOCKOPT_IP_MULTICAST_IF: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF (fd, address, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } return (_javanet_create_inetaddress (env, address)); break; case SOCKOPT_SO_BINDADDR: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS (fd, address, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } return (_javanet_create_inetaddress (env, address)); break; case SOCKOPT_SO_REUSEADDR: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS (fd, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } if (optval) return (_javanet_create_boolean (env, JNI_TRUE)); else return (_javanet_create_boolean (env, JNI_FALSE)); break; case SOCKOPT_SO_KEEPALIVE: TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE (fd, optval, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } if (optval) return (_javanet_create_boolean (env, JNI_TRUE)); else return (_javanet_create_boolean (env, JNI_FALSE)); break; default: JCL_ThrowException (env, SOCKET_EXCEPTION, "No such option"); return (0); } return (0);#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}void_javanet_shutdownInput (JNIEnv * env, jobject this){ int fd; /* Get the real file descriptor. */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { JCL_ThrowException (env, SOCKET_EXCEPTION, "Internal error: _javanet_get_option(): no native file descriptor"); return; } /* Shutdown input stream of socket. */ if (shutdown (fd, SHUT_RD) == -1) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING()); return; }}void_javanet_shutdownOutput (JNIEnv * env, jobject this){ int fd; /* Get the real file descriptor. */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { JCL_ThrowException (env, SOCKET_EXCEPTION, "Internal error: _javanet_get_option(): no native file descriptor"); return; } /* Shutdown output stream of socket. */ if (shutdown (fd, SHUT_WR) == -1) { JCL_ThrowException (env, SOCKET_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING()); return; }}/* end of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -