pcsl_tcp_client.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 380 行

C
380
字号
/* *    * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//** * @file * * Implementation of pcsl_network.h for platforms that support the winsock  * API. * * For all functions, the "handle" is the winsock handle (an int) * cast to void *.  Since winsock reads and writes to sockets are synchronous, * the context for reading and writing is always set to NULL. */#include <stdio.h>#include <winsock2.h>#include <windows.h>#include <pcsl_network.h>/* #include <win32app_export.h>, will a pcsl_event header file later. */extern HANDLE win32app_get_window_handle();#define WM_DEBUGGER      (WM_USER)#define WM_HOST_RESOLVED (WM_USER + 1)#define WM_NETWORK       (WM_USER + 2)/* For use by pcsl_network_error. */int lastError;/** * See pcsl_network.h for definition. */int pcsl_socket_open_start(	unsigned char *ipBytes,	int port,	void **pHandle,	void **pContext){    SOCKET s;    int falsebuf = 0;    int status;    struct sockaddr_in addr;    unsigned long blockingFlag = 1;    s = socket(AF_INET, SOCK_STREAM, 0);    if (INVALID_SOCKET == s) {        return PCSL_NET_IOERROR;    }    status = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,                        (char*)&falsebuf, sizeof (falsebuf));    lastError = WSAGetLastError();    if (SOCKET_ERROR == status) {        (void)closesocket(s);        return PCSL_NET_IOERROR;    }    addr.sin_family      = AF_INET;    addr.sin_port        = htons((unsigned short)port);    memcpy(&addr.sin_addr.s_addr, ipBytes, sizeof(addr.sin_addr.s_addr));    /* Note: WSAAsyncSelect sets the socket to non-blocking mode. */    WSAAsyncSelect(s, win32app_get_window_handle(), WM_NETWORK, FD_CONNECT);    status = connect(s, (struct sockaddr *)&addr, sizeof(addr));    lastError = WSAGetLastError();    *pHandle = (void*)s;    *pContext = NULL;    if (0 == status) {        /*         * connect() returned 0, this because the server is on the same host         * and the loopback address was used to connect. However there is         * a connect notification waiting in the message queue to unblock the         * caller, so tell the caller to block.         */        return PCSL_NET_WOULDBLOCK;    }    if (WSAEWOULDBLOCK == lastError) {        return PCSL_NET_WOULDBLOCK;    }    closesocket(s);    return PCSL_NET_CONNECTION_NOTFOUND;}/** * See pcsl_network.h for definition. */int pcsl_socket_open_finish(	void *handle,	void *context){    SOCKET s = (SOCKET)handle;    int status = (int)context;    /* Reset Window's message notification for this connection. */    WSAAsyncSelect(s, win32app_get_window_handle(), 0, 0);    lastError = status;    if (0 == status) {        return PCSL_NET_SUCCESS;    }    closesocket(s);    return PCSL_NET_IOERROR;}      /** * Common implementation between read_start() and read_finish(). */static int winsock_read_common(	void *handle,	unsigned char *pData,	int len,  	int *pBytesRead){    SOCKET s = (SOCKET)handle;    int bytesRead;    bytesRead = recv(s, (char*)pData, len, 0);    lastError = WSAGetLastError();    if (SOCKET_ERROR != bytesRead) {        *pBytesRead = bytesRead;        return PCSL_NET_SUCCESS;    }    if (WSAEWOULDBLOCK == lastError) {        /*         * Win32 only has one notifier per socket so always set both and close,         * the MIDP event code can handle any extra notifications.         * Do not cancel the notifications until the socket is closed.         */        WSAAsyncSelect(s, win32app_get_window_handle(), WM_NETWORK,                       FD_READ | FD_WRITE | FD_CLOSE);        return PCSL_NET_WOULDBLOCK;    }    if (WSAEINTR == lastError ||  WSAENOTSOCK == lastError) {        return PCSL_NET_INTERRUPTED;    }    return PCSL_NET_IOERROR;}/** * See pcsl_network.h for definition. */int pcsl_socket_read_start(	void *handle,	unsigned char *pData,	int len,  	int *pBytesRead,	void **pContext){    *pContext = NULL;    return winsock_read_common(handle, pData, len, pBytesRead);}/** * See pcsl_network.h for definition. */extern int pcsl_socket_read_finish(	void *handle,	unsigned char *pData,	int len,	int *pBytesRead,	void *context){    (void)context;    return winsock_read_common(handle, pData, len, pBytesRead);}/** * Common implementation between write_start() and write_finish(). */static int winsock_write_common(	void *handle,	char *pData,	int len,	int *pBytesWritten){    SOCKET s = (SOCKET)handle;    int bytesSent;    bytesSent = send(s, pData, len, 0);    lastError = WSAGetLastError();    if (SOCKET_ERROR != bytesSent) {        *pBytesWritten = bytesSent;        return PCSL_NET_SUCCESS;    }    if (WSAEWOULDBLOCK == lastError) {        /*         * Win32 only has one notifier per socket so always set both and close,         * the MIDP event code can handle any extra notifications.         * Do not cancel the notifications until the socket is closed.         */        WSAAsyncSelect(s, win32app_get_window_handle(), WM_NETWORK,                       FD_READ | FD_WRITE | FD_CLOSE);        return PCSL_NET_WOULDBLOCK;    }    if (WSAEINTR == lastError ||  WSAENOTSOCK == lastError) {        return PCSL_NET_INTERRUPTED;    }    return PCSL_NET_IOERROR;}/** * See pcsl_network.h for definition. */int pcsl_socket_write_start(	void *handle,	char *pData,	int len,	int *pBytesWritten,	void **pContext){    *pContext = NULL;    return winsock_write_common(handle, pData, len, pBytesWritten);}/** * See pcsl_network.h for definition. */int pcsl_socket_write_finish(	void *handle,	char *pData,	int len,	int *pBytesWritten,	void *context){    (void)context;    return winsock_write_common(handle, pData, len, pBytesWritten);}/** * See pcsl_network.h for definition. */int pcsl_socket_available(void *handle, int *pBytesAvailable){    SOCKET s = (SOCKET)handle;    unsigned long len = 0;    int status;    status = ioctlsocket(s, FIONREAD, &len);    lastError = WSAGetLastError();    if (SOCKET_ERROR != status) {        *pBytesAvailable = (int)len;        return PCSL_NET_SUCCESS;    }    return PCSL_NET_IOERROR;}/** * See pcsl_network.h for definition. */int pcsl_socket_shutdown_output(void *handle) {    SOCKET s = (SOCKET)handle;    int status;    status = shutdown(s, SD_SEND);    lastError = WSAGetLastError();    if (SOCKET_ERROR != status) {        return PCSL_NET_SUCCESS;    }    if (WSAENOTSOCK == lastError) {        return PCSL_NET_INTERRUPTED;    }    return PCSL_NET_IOERROR;}/** * See pcsl_network.h for definition. * * Note that this function NEVER returns PCSL_NET_WOULDBLOCK. Therefore, the  * finish() function should never be called and does nothing. */int pcsl_socket_close_start(    void *handle,    void **pContext){    SOCKET s = (SOCKET)handle;    int status;    (void)pContext;    /*     * Unblock any waiting threads, by send a close event with an interrupt     * status. Closesocket cancels async notitifications on the socket and     * does NOT send any messages.     */    PostMessage(win32app_get_window_handle(), WM_NETWORK, s,                WSAMAKESELECTREPLY(FD_CLOSE, WSAEINTR));    status = closesocket(s);    lastError = WSAGetLastError();    if (SOCKET_ERROR != status) {        return PCSL_NET_SUCCESS;    }            if (lastError == WSAEWOULDBLOCK) {        /*         * Call closesocket again, this will cause the socket to close         * in the background in a system thread, see doc for closesocket.         */        closesocket(s);        lastError = 0;        return PCSL_NET_SUCCESS;    }    return PCSL_NET_IOERROR;}/** * See pcsl_network.h for definition. * * Since the start function never returns PCSL_NET_WOULDBLOCK, this * function should never be called. */int pcsl_socket_close_finish(	void *handle,	void *context){    (void)handle;    (void)context;    return PCSL_NET_INVALID;}/** * See pcsl_network.h for definition. */char * pcsl_inet_ntoa (void *ipBytes) {    return inet_ntoa(*((struct in_addr*)ipBytes));}

⌨️ 快捷键说明

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