📄 javanet.c
字号:
_javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl", "native_fd", -1); do { TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); if (result != TARGET_NATIVE_OK) { /* Only throw an error when a "real" error occurs. */ error = TARGET_NATIVE_LAST_ERROR (); if (error != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL && error != ENOTCONN && error != ECONNRESET && error != EBADF) JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); } } while (error == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL);#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Connects to the specified destination. */void_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port){#ifndef WITHOUT_NETWORK int netaddr, fd; int result; int local_address, local_port; int remote_address, remote_port; assert (env != NULL); assert ((*env) != NULL); DBG ("_javanet_connect(): Entered _javanet_connect\n"); /* Pre-process input variables */ netaddr = _javanet_get_netaddr (env, addr); if ((*env)->ExceptionOccurred (env)) return; if (port == -1) port = 0; DBG ("_javanet_connect(): Got network address\n"); /* Grab the real socket file descriptor */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_connect(): no native file descriptor"); return; } DBG ("_javanet_connect(): Got native fd\n"); /* Connect up */ do { TARGET_NATIVE_NETWORK_SOCKET_CONNECT (fd, netaddr, port, result); if (result != TARGET_NATIVE_OK && (TARGET_NATIVE_LAST_ERROR () != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return; } } while (result != TARGET_NATIVE_OK); DBG ("_javanet_connect(): Connected successfully\n"); /* Populate instance variables */ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } _javanet_create_localfd (env, this); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } DBG ("_javanet_connect(): Created fd\n"); _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport", local_port); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } DBG ("_javanet_connect(): Set the local port\n"); TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (fd, remote_address, remote_port, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } if (remote_address == netaddr) { _javanet_set_remhost_addr (env, this, addr); } else { _javanet_set_remhost (env, this, remote_address); } if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } DBG ("_javanet_connect(): Set the remote host\n"); _javanet_set_int_field (env, this, "java/net/SocketImpl", "port", remote_port); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } DBG ("_javanet_connect(): Set the remote port\n");#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * This method binds the specified address to the specified local port. * Note that we have to set the local address and local * port public instance variables. */void_javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port, int stream){#ifndef WITHOUT_NETWORK jclass cls; jmethodID mid; jbyteArray arr = 0; jbyte *octets; jint fd; int tmpaddr; int result; int local_address, local_port; assert (env != NULL); assert ((*env) != NULL); DBG ("_javanet_bind(): Entering native bind()\n"); /* Get the address to connect to */ cls = (*env)->GetObjectClass (env, addr); if (cls == NULL) return; mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B"); if (mid == NULL) return; DBG ("_javanet_bind(): Past getAddress method id\n"); arr = (*env)->CallObjectMethod (env, addr, mid); if ((arr == NULL) || (*env)->ExceptionOccurred (env)) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_bind()"); return; } DBG ("_javanet_bind(): Past call object method\n"); octets = (*env)->GetByteArrayElements (env, arr, 0); if (octets == NULL) return; DBG ("_javanet_bind(): Past grab array\n"); /* Get the native socket file descriptor */ fd = _javanet_get_int_field (env, this, "native_fd"); if (fd == -1) { (*env)->ReleaseByteArrayElements (env, arr, octets, 0); JCL_ThrowException (env, IO_EXCEPTION, "Internal error: _javanet_bind(): no native file descriptor"); return; } DBG ("_javanet_bind(): Past native_fd lookup\n"); /* XXX NYI ??? */ _javanet_set_option (env, this, SOCKOPT_SO_REUSEADDR, _javanet_create_boolean (env, JNI_TRUE)); /* Bind the socket */ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0], octets[1], octets[2], octets[3], tmpaddr); TARGET_NATIVE_NETWORK_SOCKET_BIND (fd, tmpaddr, port, result); if (result != TARGET_NATIVE_OK) { char *errorstr = TARGET_NATIVE_LAST_ERROR_STRING (); (*env)->ReleaseByteArrayElements (env, arr, octets, 0); JCL_ThrowException (env, BIND_EXCEPTION, errorstr); return; } DBG ("_javanet_bind(): Past bind\n"); (*env)->ReleaseByteArrayElements (env, arr, octets, 0); /* Update instance variables, specifically the local port number */ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return; } if (stream) _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport", local_port); else _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl", "localPort", local_port); DBG ("_javanet_bind(): Past update port number\n"); return;#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Starts listening on a socket with the specified number of pending * connections allowed. */void_javanet_listen (JNIEnv * env, jobject this, jint queuelen){#ifndef WITHOUT_NETWORK int fd; int result; assert (env != NULL); assert ((*env) != NULL); /* 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_listen(): no native file descriptor"); return; } /* Start listening */ TARGET_NATIVE_NETWORK_SOCKET_LISTEN (fd, queuelen, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return; }#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Accepts a new connection and assigns it to the passed in SocketImpl * object. Note that we assume this is a PlainSocketImpl just like us */void_javanet_accept (JNIEnv * env, jobject this, jobject impl){#ifndef WITHOUT_NETWORK int fd, newfd; int result; int local_address, local_port; int remote_address, remote_port; assert (env != NULL); assert ((*env) != NULL); /* 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_accept(): no native file descriptor"); return; } /* Accept the connection */ do { TARGET_NATIVE_NETWORK_SOCKET_ACCEPT (fd, newfd, result); if (result != TARGET_NATIVE_OK && (TARGET_NATIVE_LAST_ERROR () != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) { if (TARGET_NATIVE_LAST_ERROR () == EAGAIN) JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout"); else JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return; } } while (result != TARGET_NATIVE_OK); /* Populate instance variables */ _javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl", "native_fd", newfd); if ((*env)->ExceptionOccurred (env)) { /* Try to make sure we close the socket since close() won't work. */ do { TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); if (result != TARGET_NATIVE_OK && (TARGET_NATIVE_LAST_ERROR () != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) return; } while (result != TARGET_NATIVE_OK); return; } TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (newfd, local_address, local_port, result); if (result != TARGET_NATIVE_OK) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); return; } _javanet_create_localfd (env, impl); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } _javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport", local_port); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (newfd, remote_address, remote_port, result); if (result != TARGET_NATIVE_OK) { JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } _javanet_set_remhost (env, impl, remote_address); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } _javanet_set_int_field (env, impl, "java/net/SocketImpl", "port", remote_port); if ((*env)->ExceptionOccurred (env)) { /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; }#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Receives a buffer from a remote host. The args are: * * buf - The byte array into which the data received will be written * offset - Offset into the byte array to start writing * len - The number of bytes to read. * addr - Pointer to 32 bit net address of host to receive from. If null, * this parm is ignored. If pointing to an address of 0, the * actual address read is stored here * port - Pointer to the port to receive from. If null, this parm is ignored. * If it is 0, the actual remote port received from is stored here * * The actual number of bytes read is returned. */int_javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset, int len, int *addr, int *port){#ifndef WITHOUT_NETWORK int fd; jbyte *p; int from_address, from_port; int received_bytes; assert (env != NULL); assert ((*env) != NULL); DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n"); /* 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_recvfrom(): no native file descriptor"); return 0; } DBG ("_javanet_recvfrom(): Got native_fd\n"); /* Get a pointer to the buffer */ p = (*env)->GetByteArrayElements (env, buf, 0); if (p == NULL) return 0; DBG ("_javanet_recvfrom(): Got buffer\n"); /* Read the data */ from_address = 0; from_port = 0; do { if (addr != NULL) { TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT (fd, p + offset, len, from_address, from_port, received_bytes); } else { TARGET_NATIVE_NETWORK_SOCKET_RECEIVE (fd, p + offset, len, received_bytes); } } while ((received_bytes == -1) && (TARGET_NATIVE_LAST_ERROR () == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)); if (received_bytes == -1) { if (TARGET_NATIVE_LAST_ERROR () == EAGAIN) JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout"); else JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); /* Cleanup and return. */ (*env)->ReleaseByteArrayElements (env, buf, p, 0); return 0; } (*env)->ReleaseByteArrayElements (env, buf, p, 0); /* Handle return addr case */ if (addr != NULL) { (*addr) = from_address; if (port != NULL) (*port) = from_port; } return (received_bytes);#else /* not WITHOUT_NETWORK */#endif /* not WITHOUT_NETWORK */}/*************************************************************************//* * Sends a buffer to a remote host. The args are: * * buf - A byte array * offset - Index into the byte array to start sendign
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -