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

📄 jni_socket.c

📁 RESIN 3.2 最新源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * @author Scott Ferguson */#ifdef WIN32#ifndef _WINSOCKAPI_ #define _WINSOCKAPI_#endif #include <windows.h>#include <winsock2.h>#include <io.h>#else#include <sys/param.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/resource.h>#include <dirent.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#ifdef EPOLL#include <sys/epoll.h>#endif#ifdef POLL#include <sys/poll.h>#else#include <sys/select.h>#endif#include <pwd.h>#include <syslog.h>#include <netdb.h>#endif#ifdef linux#include <linux/version.h>#endif#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <signal.h>#include <errno.h>/* probably system-dependent */#include <jni.h>#include "resin.h"#define STACK_BUFFER_SIZE (16 * 1024)voidcse_log(char *fmt, ...){#ifdef DEBUG    va_list list;  va_start(list, fmt);  vfprintf(stderr, fmt, list);  va_end(list);#endif}static char *q_strdup(char *str){  int len = strlen(str);  char *dup = cse_malloc(len + 1);  strcpy(dup, str);  return dup;}static intset_byte_array_region(JNIEnv *env, jbyteArray j_buf, jint offset, jint sublen,		      char *c_buf){  (*env)->SetByteArrayRegion(env, j_buf, offset, sublen, (void*) c_buf);    return 1;}static intget_byte_array_region(JNIEnv *env, jbyteArray buf, jint offset, jint sublen,		      char *buffer){  (*env)->GetByteArrayRegion(env, buf, offset, sublen, (void*) buffer);    return 1;}JNIEXPORT jlong JNICALLJava_com_caucho_vfs_JniSocketImpl_nativeAllocate(JNIEnv *env,						 jobject obj){  connection_t *conn;  conn = (connection_t *) cse_malloc(sizeof(connection_t));    memset(conn, 0, sizeof(connection_t));  conn->fd = -1;  conn->client_sin = (struct sockaddr *) conn->client_data;  conn->server_sin = (struct sockaddr *) conn->server_data;  conn->ops = &std_ops;#ifdef WIN32  // conn->event = WSACreateEvent();#endif  return (jlong) (PTR) conn;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_readNative(JNIEnv *env,					     jobject obj,					     jlong conn_fd,					     jbyteArray buf,					     jint offset,					     jint length,					     jlong timeout){  connection_t *conn = (connection_t *) (PTR) conn_fd;  int sublen;  char buffer[STACK_BUFFER_SIZE];  if (! conn || conn->fd < 0)    return -1;  conn->jni_env = env;  if (length < STACK_BUFFER_SIZE)    sublen = length;  else    sublen = STACK_BUFFER_SIZE;  sublen = conn->ops->read(conn, buffer, sublen, (int) timeout);  /* Should probably have a different response for EINTR */  if (sublen < 0)    return sublen;  set_byte_array_region(env, buf, offset, sublen, buffer);  return sublen;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniStream_readNonBlockNative(JNIEnv *env,						 jobject obj,						 jlong conn_fd,						 jbyteArray buf,						 jint offset,						 jint length){  connection_t *conn = (connection_t *) (PTR) conn_fd;  int sublen;  char buffer[STACK_BUFFER_SIZE];  if (! conn || conn->fd < 0)    return -1;  conn->jni_env = env;  if (length < STACK_BUFFER_SIZE)    sublen = length;  else    sublen = STACK_BUFFER_SIZE;  sublen = conn->ops->read_nonblock(conn, buffer, sublen);  /* Should probably have a different response for EINTR */  if (sublen < 0)    return sublen;  set_byte_array_region(env, buf, offset, sublen, buffer);  return sublen;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_writeNative(JNIEnv *env,					      jobject obj,					      jlong conn_fd,					      jbyteArray buf,					      jint offset,					      jint length){  connection_t *conn = (connection_t *) (PTR) conn_fd;  char buffer[STACK_BUFFER_SIZE];  int sublen;  int write_length = 0;  if (! conn || conn->fd < 0 || ! buf)    return -1;    conn->jni_env = env;  while (length > 0) {    int result;        if (length < sizeof(buffer))      sublen = length;    else      sublen = sizeof(buffer);    get_byte_array_region(env, buf, offset, sublen, buffer);        result = conn->ops->write(conn, buffer, sublen);        if (result < 0) {      return result;    }    length -= result;    offset += result;    write_length += result;  }  return write_length;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_writeNative2(JNIEnv *env,					       jobject obj,					       jlong conn_fd,					       jbyteArray buf1,					       jint off1,					       jint len1,					       jbyteArray buf2,					       jint off2,					       jint len2){  connection_t *conn = (connection_t *) (PTR) conn_fd;  char buffer[2 * STACK_BUFFER_SIZE];  int sublen;  int buffer_offset;  int write_length = 0;  buffer_offset = 0;  if (! conn || conn->fd < 0 || ! buf1 || ! buf2)    return -1;    conn->jni_env = env;  while (sizeof(buffer) < len1) {    sublen = sizeof(buffer);        get_byte_array_region(env, buf1, off1, sublen, buffer);          sublen = conn->ops->write(conn, buffer, sublen);    if (sublen < 0) {      /* XXX: probably should throw exception */      return sublen;    }    len1 -= sublen;    off1 += sublen;    write_length += sublen;  }  get_byte_array_region(env, buf1, off1, len1, buffer);  buffer_offset = len1;  while (buffer_offset + len2 > 0) {    int result;        if (len2 < sizeof(buffer) - buffer_offset)      sublen = len2;    else      sublen = sizeof(buffer) - buffer_offset;    get_byte_array_region(env, buf2, off2, sublen,			       buffer + buffer_offset);          result = conn->ops->write(conn, buffer, buffer_offset + sublen);    if (result < 0) {      /* XXX: probably should throw exception */      return result;    }    len2 -= sublen;    off2 += sublen;    write_length += sublen + buffer_offset;    buffer_offset = 0;  }  return write_length;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_flushNative(JNIEnv *env,					      jobject obj,					      jlong conn_fd){  connection_t *conn = (connection_t *) (PTR) conn_fd;  if (! conn)    return -1;  else    return 0;  /* return cse_flush_request(res); */}JNIEXPORT void JNICALLJava_com_caucho_vfs_JniSocketImpl_nativeClose(JNIEnv *env,					      jobject obj,					      jlong conn_fd){  connection_t *conn = (connection_t *) (PTR) conn_fd;  if (conn && conn->fd >= 0) {    conn->jni_env = env;    conn->ops->close(conn);  }}JNIEXPORT void JNICALLJava_com_caucho_vfs_JniSocketImpl_nativeFree(JNIEnv *env,					     jobject obj,					     jlong conn_fd){  connection_t *conn = (connection_t *) (PTR) conn_fd;  if (conn) {#ifdef WIN32	  /*    if (conn->event)      WSACloseEvent(conn->event);	  */#endif    cse_free(conn);  }}JNIEXPORT jboolean JNICALLJava_com_caucho_vfs_JniSocketImpl_isSecure(JNIEnv *env,                                        jobject obj,                                        jlong conn_fd){  connection_t *conn = (connection_t *) (PTR) conn_fd;  if (! conn)    return 0;    return conn->sock != 0 && conn->ssl_cipher != 0;}JNIEXPORT jstring JNICALLJava_com_caucho_vfs_JniSocketImpl_getCipher(JNIEnv *env,                                         jobject obj,                                         jlong conn_fd){  connection_t *conn = (connection_t *) (PTR) conn_fd;  if (! conn || ! conn->sock || ! conn->ssl_cipher)    return 0;  return (*env)->NewStringUTF(env, conn->ssl_cipher);}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getCipherBits(JNIEnv *env,					     jobject obj,					     jlong conn_fd){  connection_t *conn = (connection_t *) (PTR) conn_fd;  if (! conn || ! conn->sock)    return 0;  else    return conn->ssl_bits;}#ifdef POLLJNIEXPORT jboolean JNICALLJava_com_caucho_vfs_JniSocketImpl_nativeReadNonBlock(JNIEnv *env,                                                  jobject obj,                                                  jlong conn_fd,						  jint ms){  connection_t *conn = (connection_t *) (PTR) conn_fd;  struct pollfd poll_item[1];  int fd;  if (! conn)    return 0;  fd = conn->fd;  if (fd < 0)    return 0;  poll_item[0].fd = fd;  poll_item[0].events = POLLIN|POLLPRI;  poll_item[0].revents = 0;  return (poll(poll_item, 1, ms) > 0);}#else /* SELECT */JNIEXPORT jboolean JNICALLJava_com_caucho_vfs_JniSocketImpl_nativeReadNonBlock(JNIEnv *env,                                                  jobject obj,                                                  jlong conn_fd,						  jint ms){  connection_t *conn = (connection_t *) (PTR) conn_fd;  fd_set read_set;  struct timeval timeout;  int result;  int fd;  if (! conn)    return 0;  fd = conn->fd;  if (fd < 0)    return 0;  FD_ZERO(&read_set);  FD_SET((unsigned int) fd, &read_set);  timeout.tv_sec = ms / 1000;  timeout.tv_usec = (ms % 1000) * 1000;  result = select(fd + 1, &read_set, 0, 0, &timeout);  return result > 0;}#endif#ifdef AI_NUMERICHOSTstatic struct sockaddr_in *lookup_addr(JNIEnv *env, char *addr_name, int port,	    char *buffer, int *p_family, int *p_protocol,	    int *p_sin_length){  struct addrinfo hints;  struct addrinfo *addr;  struct sockaddr_in *sin;  int sin_length;  char port_name[16];    memset(&hints, 0, sizeof(hints));  hints.ai_socktype = SOCK_STREAM;  hints.ai_family = PF_UNSPEC;  hints.ai_flags = AI_NUMERICHOST;  sprintf(port_name, "%d", port);  if (getaddrinfo(addr_name, port_name, &hints, &addr)) {    resin_printf_exception(env, "java/net/SocketException", "can't find address %s", addr_name);    return 0;  }  *p_family = addr->ai_family;  *p_protocol = addr->ai_protocol;  sin_length = addr->ai_addrlen;  memcpy(buffer, addr->ai_addr, sin_length);  sin = (struct sockaddr_in *) buffer;  freeaddrinfo(addr);  *p_sin_length = sin_length;  return sin;}#elsestatic struct sockaddr_in *lookup_addr(JNIEnv *env, char *addr_name, int port,	    char *buffer, int *p_family, int *p_protocol, int *p_sin_length){  struct sockaddr_in *sin = (struct sockaddr_in *) buffer;    memset(sin, 0, sizeof(struct sockaddr_in));  *p_sin_length = sizeof(struct sockaddr_in);    sin->sin_family = AF_INET;  *p_family = AF_INET;  *p_protocol = 0;  sin->sin_addr.s_addr = inet_addr(addr_name);   sin->sin_port = htons((unsigned short) port);  return sin;}#endifstatic voidinit_server_socket(JNIEnv *env, server_socket_t *ss){  jclass jniServerSocketClass;    jniServerSocketClass = (*env)->FindClass(env, "com/caucho/vfs/JniSocketImpl");  if (jniServerSocketClass) {    ss->_isSecure = (*env)->GetFieldID(env, jniServerSocketClass,				       "_isSecure", "Z");    if (! ss->_isSecure)      resin_throw_exception(env, "com/caucho/config/ConfigException",			    "can't load _isSecure field");          ss->_localAddrBuffer = (*env)->GetFieldID(env, jniServerSocketClass,					      "_localAddrBuffer", "[B");    if (! ss->_localAddrBuffer)      resin_throw_exception(env, "com/caucho/config/ConfigException",			    "can't load _localAddrBuffer field");        ss->_localAddrLength = (*env)->GetFieldID(env, jniServerSocketClass,					      "_localAddrLength", "I");    if (! ss->_localAddrLength)      resin_throw_exception(env, "com/caucho/config/ConfigException",			    "can't load _localAddrLength field");        ss->_localPort = (*env)->GetFieldID(env, jniServerSocketClass,					"_localPort", "I");    if (! ss->_localPort)      resin_throw_exception(env, "com/caucho/config/ConfigException",			    "can't load _localPort field");          ss->_remoteAddrBuffer = (*env)->GetFieldID(env, jniServerSocketClass,					       "_remoteAddrBuffer", "[B");    if (! ss->_remoteAddrBuffer)      resin_throw_exception(env, "com/caucho/config/ConfigException",			    "can't load _remoteAddrBuffer field");        ss->_remoteAddrLength = (*env)->GetFieldID(env, jniServerSocketClass,					      "_remoteAddrLength", "I");    if (! ss->_remoteAddrLength)

⌨️ 快捷键说明

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