📄 socketprotocol.c
字号:
/* * @(#)socketProtocol.c 1.63 02/09/04 @(#) * * Copyright (c) 1999-2002 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. *//*========================================================================= * KVM *========================================================================= * SYSTEM: KVM * SUBSYSTEM: networking (Generic Connection framework) * FILE: socketProtocol.c * OVERVIEW: This file provides a default implementation of the native * functions that are needed for supporting the "socket:" and * "serversocket:" Generic Connection protocols. * AUTHOR(s): Nik Shaylor, Efren Serra *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include <kni.h>#include <stdio.h>#include <midpMalloc.h>#include "socketProtocol.h"#include "pushregistry.h"#include "configuration.h"#include "defaultLCDUI.h"#ifdef UNIX#include <unistd.h>#else#include <windows.h>#ifdef GCC#include <winsock.h>#else#ifndef _WINSOCKAPI_#include <winsock2.h>#endif /* _WINSOCKAPI_ */#endif /* GCC */#endif /* UNIX *//*========================================================================= * Definitions and declarations *=======================================================================*//* The following flag allows the code for server * sockets to be compiled out if necessary. */#ifndef NO_SERVER_SOCKETS#define NO_SERVER_SOCKETS 0 /* Include server sockets by default */#endif#if INCLUDEDEBUGCODE#define NDEBUG0(fmt) if (tracenetworking) { fprintf(stdout, fmt); }#define NDEBUG1(fmt, p1) if (tracenetworking) { fprintf(stdout, fmt, p1); }#define NDEBUG2(fmt, p1, p2) if (tracenetworking) { fprintf(stdout, fmt, p1, p2); }#define NDEBUG3(fmt, p1, p2, p3) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3); }#define NDEBUG4(fmt, p1, p2, p3, p4) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3, p4); }#define NDEBUG5(fmt, p1, p2, p3, p4, p5) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3, p4, p5); }#define NDEBUG6(fmt, p1, p2, p3, p4, p5, p6) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3, p4, p5, p6); }#else#define NDEBUG0(fmt) /**/#define NDEBUG1(fmt, p1) /**/#define NDEBUG2(fmt, p1, p2) /**/#define NDEBUG3(fmt, p1, p2, p3) /**/#define NDEBUG4(fmt, p1, p2, p3, p4) /**/#define NDEBUG5(fmt, p1, p2, p3, p4, p5) /**/#define NDEBUG6(fmt, p1, p2, p3, p4, p5, p6) /**/#endif#ifndef MAX_HOST_LENGTH#define MAX_HOST_LENGTH 256#endif /* MAX_HOST_LENGTH */#define INVALID_HANDLE -1static int socketFieldIDsObtained = 0;static jfieldID socketHandleFieldID;static int serverSocketFieldIDsObtained = 0;static jfieldID serverSocketHandleFieldID;/* delcared in defaultLCDUI.h, used in socketProtocol.c * and datagramProtocol.c */int netIndicatorCount = 0;/*========================================================================= * Protocol methods *=======================================================================*//*========================================================================= * FUNCTION: setSocketHandle() * TYPE: public instance-level operation * OVERVIEW: Set the contents of the handle field * INTERFACE: * parameters: instance, value * returns: <nothing> *=======================================================================*/static void setSocketHandle(int handle){ KNI_StartHandles(2); KNI_DeclareHandle(socketObject); KNI_GetThisPointer(socketObject); if (!socketFieldIDsObtained) { KNI_DeclareHandle(socketClass); KNI_GetObjectClass(socketObject, socketClass); socketHandleFieldID = KNI_GetFieldID(socketClass, "handle","I"); socketFieldIDsObtained = 1; } KNI_SetIntField(socketObject, socketHandleFieldID, (jint)handle); KNI_EndHandles(); NDEBUG1("setSocketHandle handle=%d\n", handle);}/*========================================================================= * function: getSocketHandle() * TYPE: private instance-level operation * OVERVIEW: Get the contents of the handle field * INTERFACE: * parameters: instance, field * returns: value *=======================================================================*/static int getSocketHandle(){ int handle = 0; KNI_StartHandles(2); KNI_DeclareHandle(socketObject); KNI_GetThisPointer(socketObject); if (!socketFieldIDsObtained) { KNI_DeclareHandle(socketClass); KNI_GetObjectClass(socketObject, socketClass); socketHandleFieldID = KNI_GetFieldID(socketClass, "handle","I"); socketFieldIDsObtained = 1; } handle = (int)KNI_GetIntField(socketObject, socketHandleFieldID); KNI_EndHandles(); NDEBUG1("getSocketHandle handle=%d\n", handle); return handle;}/*========================================================================= * FUNCTION: setServerSocketHandle() * TYPE: public instance-level operation * OVERVIEW: Set the contents of the handle field * INTERFACE: * parameters: instance, value, field * returns: <nothing> *=======================================================================*/static void setServerSocketHandle(long handle){ KNI_StartHandles(2); KNI_DeclareHandle(serverSocketObject); KNI_GetThisPointer(serverSocketObject); if (!serverSocketFieldIDsObtained) { KNI_DeclareHandle(serverSocketClass); KNI_GetObjectClass(serverSocketObject, serverSocketClass); serverSocketHandleFieldID = KNI_GetFieldID(serverSocketClass, "handle","I"); serverSocketFieldIDsObtained = 1; } KNI_SetIntField(serverSocketObject, serverSocketHandleFieldID, handle); KNI_EndHandles();}/*========================================================================= * function: getServerSocketHandle() * TYPE: private instance-level operation * OVERVIEW: Get the contents of the handle field * INTERFACE: * parameters: instance, field * returns: value *=======================================================================*/static long getServerSocketHandle(){ long handle = 0; KNI_StartHandles(2); KNI_DeclareHandle(serverSocketObject); KNI_GetThisPointer(serverSocketObject); if (!serverSocketFieldIDsObtained) { KNI_DeclareHandle(serverSocketClass); KNI_GetObjectClass(serverSocketObject, serverSocketClass); serverSocketHandleFieldID = KNI_GetFieldID(serverSocketClass, "handle","I"); serverSocketFieldIDsObtained = 1; } handle = (int)KNI_GetIntField(serverSocketObject, serverSocketHandleFieldID); KNI_EndHandles(); NDEBUG1("getServerSocketHandle handle=%ld\n", handle); return handle;}/*========================================================================= * FUNCTION: open0() * CLASS: com.sun.midp.io.j2me.socket.Protocol * TYPE: virtual native function * OVERVIEW: Open a TCP socket * INTERFACE (operand stack manipulation): * parameters: this, host, port * returns: none, sets the handle field of the object *=======================================================================*/KNIEXPORT KNI_RETURNTYPE_VOIDJava_com_sun_midp_io_j2me_socket_Protocol_open0(){ char host[MAX_HOST_LENGTH]; int hostLength; int port; char* pszException = NULL; int handle = INVALID_HANDLE; NDEBUG0("socket::open0"); KNI_StartHandles(1); KNI_DeclareHandle(hostObject); KNI_GetParameterAsObject(1, hostObject); hostLength = KNI_GetArrayLength(hostObject); if (hostLength > MAX_HOST_LENGTH) { setSocketHandle(INVALID_HANDLE); KNI_ThrowNew("java/lang/IllegalArugmentException", "Host too long"); } else { KNI_GetRawArrayRegion(hostObject, 0, hostLength, (jbyte*)host); host[hostLength] = '\0'; NDEBUG1(" host='%s'", host); port = (int)KNI_GetParameterAsInt(2); NDEBUG1(" port=%d", port); /* This will block the KVM on slow wireless networks. */ handle = prim_com_sun_midp_io_j2me_socket_Protocol_open0(host, port, &pszException); netIndicatorCount++; NDEBUG1(" handle = %d", handle); if (pszException != NULL) { NDEBUG2(" error = %d exception = %s", netError(), pszException); setSocketHandle(INVALID_HANDLE); KNI_ThrowNew(pszException, "TCP open"); } else {#ifndef BLOCKING_NET_IO /* For non-blocking systems only */ prim_com_sun_midp_io_j2me_socket_Protocol_setNonBlocking(handle);#endif setSocketHandle(handle); } } KNI_EndHandles(); NDEBUG0("\n"); KNI_ReturnVoid();}/*========================================================================= * FUNCTION: int read0(byte[], int, int) * CLASS: com.sun.midp.io.j2me.socket.Protocol * TYPE: virtual native function * OVERVIEW: Read from a TCP socket * INTERFACE (operand stack manipulation): * parameters: this, buffer, offset, length * returns: number of chars read or -1 if at EOF *=======================================================================*/KNIEXPORT KNI_RETURNTYPE_INTJava_com_sun_midp_io_j2me_socket_Protocol_read0(){ static char errorMsg[40]; /* Error message to send back to Java */ char* pBuffer; int length; int offset; int handle; int bytesRead; length = (int)KNI_GetParameterAsInt(3); pBuffer = (char*)midpMalloc(length); if (pBuffer == NULL) { KNI_ThrowNew("java/lang/OutOfMemoryError", "TCP read buffer"); KNI_ReturnInt(0); } offset = (int)KNI_GetParameterAsInt(2); handle = getSocketHandle(); NDEBUG3("socket::read0 off=%d len=%d handle=%d\n", offset, length, handle); bytesRead = prim_com_sun_midp_io_j2me_socket_Protocol_read0(handle, pBuffer, length); NDEBUG1("socket::read0 bytesRead=%d\n", bytesRead); if (bytesRead == IO_WOULDBLOCK) { /* no data ready, try again later */ bytesRead = 0; } else if (bytesRead < 0) { NDEBUG1("socket::read0 ne=%d\n", netError()); if (bytesRead == IO_INTERRUPTED) { KNI_ThrowNew("java/io/InterruptedIOException", ""); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -