⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nbio.c

📁 实现非阻塞方式IO(NBIO)的java类
💻 C
📖 第 1 页 / 共 3 页
字号:
  memset((char *)&him,  0, sizeof(him));  him.sin_port = htons((short)port);  him.sin_addr.s_addr = (unsigned long)htonl(inet_address);  him.sin_family = inet_family;  if ((ret = bind(fd, (struct sockaddr *)&him, sizeof(him))) < 0) {    if (errno == EACCES) {      THROW_EXCEPTION(env, "java/net/BindException", strerror(errno));    } else {      THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));    }    return;  }  cls = (*env)->GetObjectClass(env, this);  fid = (*env)->GetFieldID(env, cls, "address", "Ljava/net/InetAddress;");  (*env)->SetObjectField(env, this, fid, address);  fid = (*env)->GetFieldID(env, cls, "port", "I");  (*env)->SetIntField(env, this, fid, port);  fid = (*env)->GetFieldID(env, cls, "localport", "I");  /* Set local port value */  if (port == 0) {    /* Set localport value -- may have been previously set by bind operation */    int len = sizeof(him);    if (getsockname(fd,(struct sockaddr *)&him, &len) == -1) {      THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));      return;    }    (*env)->SetIntField(env, this, fid, ntohs(him.sin_port));  } else {    (*env)->SetIntField(env, this, fid, port);  }  return;}  /* * Class:     ninja2_core_io_0005fcore_nbio_NonblockingSocketImpl * Method:    nbSocketListen * Signature: (I)V */JNIEXPORT void JNICALL Java_ninja2_core_io_1core_nbio_NonblockingSocketImpl_nbSocketListen (JNIEnv *env, jobject this, jint count) {  int fd;  jclass cls = (*env)->GetObjectClass(env, this);  jfieldID fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  jobject fdobj = (*env)->GetObjectField(env, this, fid);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  cls = (*env)->GetObjectClass(env, fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  fd = (*env)->GetIntField(env, fdobj, fid);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  if (listen(fd, count) < 0) {    THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));    return;  }}/* * Class:     ninja2_core_io_0005fcore_nbio_NonblockingSocketImpl * Method:    nbSocketAccept * Signature: (Lninja2/core/io_core/nbio/NonblockingSocketImpl;)V */JNIEXPORT jint JNICALL Java_ninja2_core_io_1core_nbio_NonblockingSocketImpl_nbSocketAccept (JNIEnv *env, jobject this, jobject newsocket, jboolean block) {  int fd, newfd;  struct sockaddr_in him;  int len, localport;  jobject sptr_inetaddr, sptr_fdobj;  jclass cls = (*env)->GetObjectClass(env, this);  jfieldID fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  jobject fdobj = (*env)->GetObjectField(env, this, fid);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  cls = (*env)->GetObjectClass(env, fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  fd = (*env)->GetIntField(env, fdobj, fid);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  if (newsocket == NULL) {     THROW_EXCEPTION(env, "java/lang/NullPointerException", "newsocket is NULL");    return -1;  }  /* We expect that the 'fd' field of the newsocket has   * been created outside of this method (but not initialized).   */  cls = (*env)->GetObjectClass(env, newsocket);  fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  sptr_fdobj = (*env)->GetObjectField(env, newsocket, fid);  if (sptr_fdobj == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "newsocket uninitialized");    return -1;  }  /* XXX MDW This is not threadsafe */  if (!block) {    nbio_make_nonblocking(env, fd);  } else {    nbio_make_blocking(env, fd);  }  DEBUG(fprintf(stderr,"NBIO: Doing accept() on fd=%d\n", fd));#ifdef linux  len = sizeof(him);#endif #ifdef SOLARIS  len = sizeof(struct sockaddr); #endif  newfd = nbio_real_accept(fd, (struct sockaddr *)&him, &len);  if (newfd < 0) {    if (!block && errno == EWOULDBLOCK) return -1;    else {      THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));      return -1;    }  }  nbio_make_nonblocking(env, newfd);  nbio_disable_nagle(env, newfd);  cls = (*env)->GetObjectClass(env, sptr_fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  // fd == -1 indicates not initialized  (*env)->SetIntField(env, sptr_fdobj, fid, newfd);  cls = (*env)->GetObjectClass(env, this);  fid = (*env)->GetFieldID(env, cls, "localport", "I");  localport = (*env)->GetIntField(env, this, fid);  /* Create empty InetAddress and initialize it */  DEBUG(fprintf(stderr,"NBIO: accept() creating new InetAddress\n"));  cls = (*env)->FindClass(env, "java/net/InetAddress");  if (cls == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "Cannot find java.net.InetAddress class");    return -1;  }  sptr_inetaddr = (*env)->AllocObject(env, cls);  DEBUG(fprintf(stderr,"NBIO: accept() initializing new InetAddress\n"));  fid = (*env)->GetFieldID(env, cls, "address", "I");  (*env)->SetIntField(env, sptr_inetaddr, fid, ntohl(him.sin_addr.s_addr));  fid = (*env)->GetFieldID(env, cls, "family", "I");  (*env)->SetIntField(env, sptr_inetaddr, fid, him.sin_family);  cls = (*env)->GetObjectClass(env, newsocket);  fid = (*env)->GetFieldID(env, cls, "port", "I");  (*env)->SetIntField(env, newsocket, fid, ntohs(him.sin_port));  fid = (*env)->GetFieldID(env, cls, "localport", "I");  (*env)->SetIntField(env, newsocket, fid, localport);  fid = (*env)->GetFieldID(env, cls, "address", "Ljava/net/InetAddress;");  (*env)->SetObjectField(env, newsocket, fid, sptr_inetaddr);  return 0;}/* * Class:     ninja2_core_io_0005fcore_nbio_NonblockingSocketImpl * Method:    nbSocketAvailable * Signature: ()I */JNIEXPORT jint JNICALL Java_ninja2_core_io_1core_nbio_NonblockingSocketImpl_nbSocketAvailable (JNIEnv *env, jobject this) {  int fd;  int bytes;  jclass cls = (*env)->GetObjectClass(env, this);  jfieldID fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  jobject fdobj = (*env)->GetObjectField(env, this, fid);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  cls = (*env)->GetObjectClass(env, fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  fd = (*env)->GetIntField(env, fdobj, fid);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }#ifdef linux  if (ioctl(fd, FIONREAD, &bytes) < 0) {#endif /* linux */#ifdef SOLARIS  if (ioctl(fd, I_NREAD, &bytes) < 0) {#endif /* SOLARIS */    THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));    return;  }  DEBUG(fprintf(stderr,"NBIO: nbSocketAvailable called, %d bytes available\n", bytes));  return bytes;}/* * Class:     ninja2_core_io_0005fcore_nbio_NonblockingSocketImpl * Method:    nbSocketClose * Signature: ()V */JNIEXPORT void JNICALL Java_ninja2_core_io_1core_nbio_NonblockingSocketImpl_nbSocketClose (JNIEnv * env, jobject this) {  int fd;   jclass cls = (*env)->GetObjectClass(env, this);  jfieldID fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  jobject fdobj = (*env)->GetObjectField(env, this, fid);  if (fdobj == NULL) {    //THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  cls = (*env)->GetObjectClass(env, fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  fd = (*env)->GetIntField(env, fdobj, fid);  if (fd == -1) {    //THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  close(fd);  (*env)->SetIntField(env, fdobj, fid, 0);}/* NonblockingSocketInputStream *******************************************//* * Class:     ninja2_core_io_0005fcore_nbio_NonblockingSocketInputStream * Method:    nbSocketRead * Signature: ([BII)I */JNIEXPORT jint JNICALL Java_ninja2_core_io_1core_nbio_NonblockingSocketInputStream_nbSocketRead (JNIEnv *env, jobject this, jbyteArray b, jint off, jint len) {  int fd;  jclass cls;  jfieldID fid;  jobject fdobj;  int datalen;  char *data;  int n;  DEBUG(fprintf(stderr,"NBIO: nbSocketRead called, off=%d len=%d\n", off, len));  cls = (*env)->GetObjectClass(env, this);  fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  fdobj = (*env)->GetObjectField(env, this, fid);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  cls = (*env)->GetObjectClass(env, fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  fd = (*env)->GetIntField(env, fdobj, fid);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  if (b == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "null byte array passed to nbSocketRead");    return;  }  datalen = (*env)->GetArrayLength(env, b);  if (len < 0 || len + off > datalen) {    THROW_EXCEPTION(env, "java/lang/ArrayIndexOutOfBoundsException", "len must be >= 0 and len + off <= array length");  }  data = (*env)->GetByteArrayElements(env, b, NULL);  n = nbio_real_read(fd, data+off, len);    DEBUG(fprintf(stderr,"NBIO: nbSocketRead: off is %d, len is %d, got %d, errno is %d\n", off, len, n, errno));  if (n == 0) {    // Socket was closed     (*env)->ReleaseByteArrayElements(env, b, data, JNI_ABORT);    return -1; // EOF  } else if (n < 0) {    if (errno == EAGAIN) {      (*env)->ReleaseByteArrayElements(env, b, data, JNI_ABORT);      return 0; // No data returned    } else {      THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));      (*env)->ReleaseByteArrayElements(env, b, data, JNI_ABORT);      return -1; // error    }  }  (*env)->ReleaseByteArrayElements(env, b, data, 0);  return n;}/* * Class:     ninja2_core_io_0005fcore_nbio_NonblockingSocketOutputStream * Method:    nbSocketWrite * Signature: ([BII)I */JNIEXPORT jint JNICALL Java_ninja2_core_io_1core_nbio_NonblockingSocketOutputStream_nbSocketWrite (JNIEnv *env, jobject this, jbyteArray b, jint off, jint len) {  int fd;  jclass cls;  jfieldID fid;  jobject fdobj;  int datalen;  char *data;  int n;  DEBUG(fprintf(stderr,"NBIO: nbSocketWrite called, off=%d len=%d\n", off, len));  cls = (*env)->GetObjectClass(env, this);  fid = (*env)->GetFieldID(env, cls, "fd", "Lninja2/core/io_core/nbio/NBIOFileDescriptor;");  fdobj = (*env)->GetObjectField(env, this, fid);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  cls = (*env)->GetObjectClass(env, fdobj);  fid = (*env)->GetFieldID(env, cls, "fd", "I");  fd = (*env)->GetIntField(env, fdobj, fid);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  if (b == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "null byte array passed to nbSocketWrite");    return;  }  datalen = (*env)->GetArrayLength(env, b);  if (len < 0 || len + off > datalen) {    THROW_EXCEPTION(env, "java/lang/ArrayIndexOutOfBoundsException", "len must be >= 0 and len + off <= array length");  }  data = (*env)->GetByteArrayElements(env, b, NULL);  n = nbio_real_write(fd, data+off, len);    DEBUG(fprintf(stderr,"NBIO: nbSocketWrite: off is %d, len is %d, got %d, errno is %d\n", off, len, n, errno));  if (n < 0) {    if (errno == EAGAIN) {      (*env)->ReleaseByteArrayElements(env, b, data, JNI_ABORT);      return 0; // No data returned    } else {      THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));      (*env)->ReleaseByteArrayElements(env, b, data, JNI_ABORT);      return -1; // error    }  }  (*env)->ReleaseByteArrayElements(env, b, data, JNI_ABORT);  return n;}/* SelectSetDevPollImpl ******************************************************/#ifndef HAS_DEVPOLLJNIEXPORT jboolean JNICALL Java_ninja2_core_io_1core_nbio_SelectSetDevPollImpl_supported(JNIEnv *env, jclass cls) {  /* Safe setting when compiling on systems where /dev/poll not available */  return JNI_FALSE;}#else  /* HAS_DEVPOLL *//* Define to use B-Tree to map fd to selitemobj#undef USE_BTREE    /* Max number of file descriptors if flat table used */#define MAX_FDS 4096typedef struct devpoll_impl_state {  int devpoll_fd;  int max_retevents;  struct pollfd *retevents;#ifdef USE_BTREE  btree_node *tree;#else  jobject selitems[MAX_FDS];#endif} devpoll_impl_state;JNIEXPORT jboolean JNICALL Java_ninja2_core_io_1core_nbio_SelectSetDevPollImpl_supported(JNIEnv *env, jclass cls) {  struct stat statbuf;  /* If we were compiled on a system with /dev/poll, but running where   * it's not available, return false   */  if (stat("/dev/poll", &statbuf) == 0) {    return JNI_TRUE;  } else {    return JNI_FALSE;  }}JNIEXPORT void JNICALL Java_ninja2_core_io_1core_nbio_SelectSetDevPollImpl_init (JNIEnv * env, jobject this, jint max_retevents) {  jclass cls;  jfieldID fid;  devpoll_impl_state *state;  int i;  DEBUG(fprintf(stderr,"SelectSetDevPollImpl.init(%d) called\n", max_retevents));      // Allocate state  state = (devpoll_impl_state *)malloc(sizeof(devpoll_impl_state));  if (state == NULL) {    THROW_EXCEPTION(env, "java/lang/OutOfMemoryError", "Cannot allocate devpoll_impl_state");    return;  }  // Set state field  cls = (*env)->GetObjectClass(env, this);  fid = (*env)->GetFieldID(env, cls, "native_state", "J");  (*env)->SetLongField(env, this, fid, (jlong)state);  DEBUG(fprintf(stderr,"SelectSetDevPollImpl.init set state field\n"));  state->max_retevents = max_retevents;  state->devpoll_fd = open("/dev/poll", O_RDWR);  if (state->devpoll_fd < 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -