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

📄 nbio.c

📁 The Staged Event-Driven Architecture (SEDA) is a new design for building scalable Internet services.
💻 C
📖 第 1 页 / 共 4 页
字号:
  return JNI_TRUE;}/* * Class:     seda_nbio_NonblockingSocketImpl * Method:    nbSocketBind * Signature: (Ljava/net/InetAddress;I)V */JNIEXPORT void JNICALL Java_seda_nbio_NonblockingSocketImpl_nbSocketBind (JNIEnv *env, jobject this, jobject address, jint port) {  int fd, inet_address, inet_family;  struct sockaddr_in him;  int ret;  jobject fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }    /* A bind address of NULL represents AF_INET/INADDR_ANY */  if (address == NULL) {     inet_address = INADDR_ANY;    inet_family = AF_INET;  } else {    inet_address = (*env)->GetIntField(env, address, FID_java_net_InetAddress_address);    inet_family = AF_INET;  }  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) {     // JRVB: some occurrences of errno - should have been myerrno    int myerrno = errno;    fprintf(stderr,"bind: returned %d, errno %d (%s)\n", ret, myerrno, strerror(myerrno));    if (myerrno == EACCES) {      THROW_EXCEPTION(env, "java/net/BindException", strerror(myerrno));    } else {      THROW_EXCEPTION(env, "java/net/SocketException", strerror(myerrno));    }    return;  }  (*env)->SetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_address, address);  (*env)->SetIntField(env, this, FID_seda_nbio_NonblockingSocketImpl_port, port);  /* 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_seda_nbio_NonblockingSocketImpl_localport, ntohs(him.sin_port));  } else {    (*env)->SetIntField(env, this, FID_seda_nbio_NonblockingSocketImpl_localport, port);  }  return;}  /* * Class:     seda_nbio_NonblockingSocketImpl * Method:    nbSocketListen * Signature: (I)V */JNIEXPORT void JNICALL Java_seda_nbio_NonblockingSocketImpl_nbSocketListen (JNIEnv *env, jobject this, jint count) {  int fd;  jobject fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  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:     seda_nbio_NonblockingSocketImpl * Method:    nbSocketAccept * Signature: (Lseda/nbio/NonblockingSocketImpl;)V */JNIEXPORT jint JNICALL Java_seda_nbio_NonblockingSocketImpl_nbSocketAccept (JNIEnv *env, jobject this, jobject newsocket, jboolean block) {  int fd, newfd;  jclass cls;  struct sockaddr_in him;  int len, localport;  jobject sptr_inetaddr, sptr_fdobj;  jobject fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  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).   */  sptr_fdobj = (*env)->GetObjectField(env, newsocket, FID_seda_nbio_NonblockingSocketImpl_fd);  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));#if defined(linux) || defined(__FreeBSD__)  len = sizeof(him);#endif #ifdef SOLARIS  len = sizeof(struct sockaddr); #endif  newfd = 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;    }  }  DEBUG(fprintf(stderr,"NBIO: accept() on fd=%d returned %d\n", fd, newfd));  nbio_make_nonblocking(env, newfd);  nbio_disable_nagle(env, newfd);  (*env)->SetIntField(env, sptr_fdobj, FID_seda_nbio_NBIOFileDescriptor_fd, newfd);  localport = (*env)->GetIntField(env, this, FID_seda_nbio_NonblockingSocketImpl_localport);  /* 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"));  (*env)->SetIntField(env, sptr_inetaddr, FID_java_net_InetAddress_address, ntohl(him.sin_addr.s_addr));  // In JDK 1.4 the meaning of 'family' changed in InetAddress, so don't  // set it here.  //(*env)->SetIntField(env, sptr_inetaddr, FID_java_net_InetAddress_family, him.sin_family);  (*env)->SetIntField(env, newsocket, FID_seda_nbio_NonblockingSocketImpl_port, ntohs(him.sin_port));  (*env)->SetIntField(env, newsocket, FID_seda_nbio_NonblockingSocketImpl_localport, localport);  (*env)->SetObjectField(env, newsocket, FID_seda_nbio_NonblockingSocketImpl_address, sptr_inetaddr);  return 0;}/* * Class:     seda_nbio_NonblockingSocketImpl * Method:    nbSocketAvailable * Signature: ()I */JNIEXPORT jint JNICALL Java_seda_nbio_NonblockingSocketImpl_nbSocketAvailable (JNIEnv *env, jobject this) {  int fd;  int bytes;  jobject fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }#if defined(linux) || defined(__FreeBSD__)  if (ioctl(fd, FIONREAD, &bytes) < 0) {#endif /* linux or __FreeBSD__ */#ifdef SOLARIS  if (ioctl(fd, I_NREAD, &bytes) < 0) {#endif /* SOLARIS */    THROW_EXCEPTION(env, "java/net/SocketException", strerror(errno));    return -1;  }  DEBUG(fprintf(stderr,"NBIO: nbSocketAvailable called, %d bytes available\n", bytes));  return bytes;}/* * Class:     seda_nbio_NonblockingSocketImpl * Method:    nbSocketClose * Signature: ()V */JNIEXPORT void JNICALL Java_seda_nbio_NonblockingSocketImpl_nbSocketClose (JNIEnv * env, jobject this) {  int fd;   jobject fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_fd);  if (fdobj == NULL) {    return;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  if (fd == -1) {    return;  }  close(fd);  (*env)->SetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd, -1);}/* NonblockingSocketInputStream *******************************************//* * Class:     seda_nbio_NonblockingSocketInputStream * Method:    nbSocketRead * Signature: ([BII)I */JNIEXPORT jint JNICALL Java_seda_nbio_NonblockingSocketInputStream_nbSocketRead (JNIEnv *env, jobject this, jbyteArray b, jint off, jint len) {  int fd;  jobject fdobj;  int datalen;  char *data;  int n;  DEBUG(fprintf(stderr,"NBIO: nbSocketRead called, off=%d len=%d\n", off, len));  fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketInputStream_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  if (b == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "null byte array passed to nbSocketRead");    return -1;  }  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 = 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:     seda_nbio_NonblockingSocketOutputStream * Method:    nbSocketWrite * Signature: ([BII)I */JNIEXPORT jint JNICALL Java_seda_nbio_NonblockingSocketOutputStream_nbSocketWrite (JNIEnv *env, jobject this, jbyteArray b, jint off, jint len) {  int fd;  jobject fdobj;  int datalen;  char *data;  int n;  DEBUG(fprintf(stderr,"NBIO: nbSocketWrite called, off=%d len=%d\n", off, len));  fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketOutputStream_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }  if (b == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "null byte array passed to nbSocketWrite");    return -1;  }  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 = 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) || (errno == EINTR)) {      (*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;}/* UDP support code below *//* * Class:     seda_nbio_NonblockingSocketImpl * Method:    nbReceive */JNIEXPORT jint JNICALL Java_seda_nbio_NonblockingSocketImpl_nbReceive(JNIEnv *env, jobject this, jobject packet) {  jbyteArray data;  jbyte* recvdata;  jint length, offset;  struct sockaddr_in from;  int fromlength;  int fd, ret, sz;  jclass cls;   jobject addrobj;  jobject fdobj;  DEBUG(fprintf(stderr,"NBIO: nbReceive called\n"));  fdobj = (*env)->GetObjectField(env, this, FID_seda_nbio_NonblockingSocketImpl_fd);  if (fdobj == NULL) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }   if(packet == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "packet is null in nbReceive");    return -1;  }  fd = (*env)->GetIntField(env, fdobj, FID_seda_nbio_NBIOFileDescriptor_fd);  if (fd == -1) {    THROW_EXCEPTION(env, "java/net/SocketException", "socket closed");    return -1;  }    data = (*env)->GetObjectField(env, packet, FID_java_net_DatagramPacket_buf);  if(data == NULL) {    THROW_EXCEPTION(env, "java/lang/NullPointerException", "data buffer in nbReceive is null");    return -1;  }

⌨️ 快捷键说明

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