📄 ilibasyncsocket.c
字号:
/* * INTEL CONFIDENTIAL * Copyright (c) 2002, 2003 Intel Corporation. All rights reserved. * * The source code contained or described herein and all documents * related to the source code ("Material") are owned by Intel * Corporation or its suppliers or licensors. Title to the * Material remains with Intel Corporation or its suppliers and * licensors. The Material contains trade secrets and proprietary * and confidential information of Intel or its suppliers and * licensors. The Material is protected by worldwide copyright and * trade secret laws and treaty provisions. No part of the Material * may be used, copied, reproduced, modified, published, uploaded, * posted, transmitted, distributed, or disclosed in any way without * Intel's prior express written permission. * No license under any patent, copyright, trade secret or other * intellectual property right is granted to or conferred upon you * by disclosure or delivery of the Materials, either expressly, by * implication, inducement, estoppel or otherwise. Any license * under such intellectual property rights must be express and * approved by Intel in writing. * * $Workfile: ILibAsyncSocket.c * $Revision: #1.0.1799.42459 * $Author: Intel Corporation, Intel Device Builder * $Date: Wednesday, January 19, 2005 * * * */#define MEMORYCHUNKSIZE 4096#ifdef MEMORY_CHECK #include <assert.h> #define MEMCHECK(x) x#else #define MEMCHECK(x)#endif#if defined (_WIN32_WCE) #define _CRTDBG_MAP_ALLOC #include <math.h> #include <winerror.h> #include <stdlib.h> #include <stdio.h> #include <stddef.h> #include <string.h> #include <winsock.h> #include <wininet.h> #include <windows.h> #include <winioctl.h> #include <winbase.h>#elif defined(WIN32) #define _CRTDBG_MAP_ALLOC #include <math.h> #include <winerror.h> #include <stdlib.h> #include <stdio.h> #include <stddef.h> #include <string.h> #ifdef WINSOCK2 #include <winsock2.h> #include <ws2tcpip.h> #else #include <winsock.h> #include <wininet.h> #endif #include <windows.h> #include <winioctl.h> #include <winbase.h> #include <crtdbg.h>#elif defined(_POSIX) #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/time.h> #include <netdb.h> #include <string.h> #include <sys/ioctl.h> #include <net/if.h> #include <sys/utsname.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <fcntl.h> #include <errno.h>#endif#include "ILibParsers.h"#include "ILibAsyncSocket.h"#if defined(WIN32) && !defined(_WIN32_WCE) #include <errno.h>#elif defined(_POSIX) #include <errno.h> #include <semaphore.h> extern int errno;#endif#define DEBUGSTATEMENT(x)#ifdef SEMAPHORE_TRACKING#define SEM_TRACK(x) xvoid AsyncSocket_TrackLock(const char* MethodName, int Occurance, void *data){ char v[100]; sprintf(v," LOCK[%s, %d] (%x)\r\n",MethodName,Occurance,data);#ifdef WIN32 OutputDebugString(v);#else printf(v);#endif}void AsyncSocket_TrackUnLock(const char* MethodName, int Occurance, void *data){ char v[100]; sprintf(v,"UNLOCK[%s, %d] (%x)\r\n",MethodName,Occurance,data);#ifdef WIN32 OutputDebugString(v);#else printf(v);#endif}#else#define SEM_TRACK(x)#endifstruct AsyncSocket_SendData{ char* buffer; int bufferSize; int bytesSent; int UserFree; struct AsyncSocket_SendData *Next;};struct AsyncSocketModule{ void (*PreSelect)(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime); void (*PostSelect)(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset); void (*Destroy)(void* object); void *Chain; unsigned int PendingBytesToSend; unsigned int TotalBytesSent; #ifdef _WIN32_WCE SOCKET internalSocket; #elif defined(WIN32) SOCKET internalSocket; #elif defined(_POSIX) int internalSocket; #endif int RemoteIPAddress; int LocalIPAddress; void(*OnData)(void* socketModule,char* buffer,int *p_beginPointer, int endPointer,void (**InterruptPtr)(void *socketModule, void *user), void **user, int *PAUSE); void(*OnConnect)(void* socketModule, int OK, void *user); void(*OnDisconnect)(void* socketModule, void *user); void(*OnSendOK)(void *socketModule, void *user); void(*OnInterrupt)(void *socketModule, void *user); ILibAsyncSocket_OnBufferReAllocated OnBufferReAllocated; void *LifeTime; void *user; int IsFree; int PAUSE; int FinConnect; int BeginPointer; int EndPointer; char* buffer; int MallocSize; int InitialSize; struct AsyncSocket_SendData *PendingSend_Head; struct AsyncSocket_SendData *PendingSend_Tail;};void ILibAsyncSocket_PostSelect(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset);void ILibAsyncSocket_PreSelect(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime);/// <summary>/// An internal method called by Chain as Destroy, to cleanup AsyncSocket/// </summary>/// <param name="socketModule">The AsyncSocketModule</param>static void ILibAsyncSocket_Destroy(void *socketModule){ struct AsyncSocketModule* module = (struct AsyncSocketModule*)socketModule; struct AsyncSocket_SendData *temp,*current; // // Close socket if necessary // if(module->internalSocket!=~0) { #ifdef _WIN32_WCE closesocket(module->internalSocket); #elif defined(WIN32) closesocket(module->internalSocket); #elif defined(_POSIX) close(module->internalSocket); #endif } // // Call the interrupt event if necessary // if(module->IsFree==0) { if(module->OnInterrupt!=NULL) { module->OnInterrupt(module,module->user); } } // // Free the buffer if necessary // if(module->buffer!=NULL) { free(module->buffer); module->buffer = NULL; module->MallocSize = 0; } // // Clear all the data that is pending to be sent // temp=current=module->PendingSend_Head; while(current!=NULL) { temp = current->Next; if(current->UserFree==0) { free(current->buffer); } free(current); current = temp; }}void ILibAsyncSocket_SetReAllocateNotificationCallback(void *AsyncSocketToken, ILibAsyncSocket_OnBufferReAllocated Callback){ ((struct AsyncSocketModule*)AsyncSocketToken)->OnBufferReAllocated = Callback;}/// <summary>/// Creates a new AsyncSocket handler/// </summary>/// <param name="Chain">The ILibLifeTime object to add the timed callback to</param>/// <param name="initialBufferSize">The initial size of the receive buffer</param>/// <param name="OnData">Function Pointer that triggers when Data is received</param>/// <param name="OnConnect">Function Pointer that triggers upon successfull connection establishment</param>/// <param name="OnDisconnect">Function Pointer that triggers upon disconnect</param>/// <param name="OnSendOK">Function Pointer that triggers when pending sends are complete</param>/// <returns>An ILibAsyncSocket token</returns>void* ILibCreateAsyncSocketModule(void *Chain, int initialBufferSize, void(*OnData)(void* socketModule,char* buffer,int *p_beginPointer, int endPointer, void (**InterruptPtr)(void *socketModule, void *user),void **user, int *PAUSE), void(*OnConnect)(void* socketModule, int Connected, void *user),void(*OnDisconnect)(void* socketModule, void *user),void(*OnSendOK)(void *socketModule, void *user)){ struct AsyncSocketModule *RetVal = (struct AsyncSocketModule*)malloc(sizeof(struct AsyncSocketModule)); memset(RetVal,0,sizeof(struct AsyncSocketModule)); RetVal->PreSelect = &ILibAsyncSocket_PreSelect; RetVal->PostSelect = &ILibAsyncSocket_PostSelect; RetVal->Destroy = &ILibAsyncSocket_Destroy; RetVal->IsFree = 1; RetVal->internalSocket = -1; RetVal->OnData = OnData; RetVal->OnConnect = OnConnect; RetVal->OnDisconnect = OnDisconnect; RetVal->OnSendOK = OnSendOK; RetVal->buffer = (char*)malloc(initialBufferSize); RetVal->InitialSize = initialBufferSize; RetVal->MallocSize = initialBufferSize; RetVal->LifeTime = ILibCreateLifeTime(Chain); RetVal->Chain = Chain; ILibAddToChain(Chain,RetVal); return((void*)RetVal);}/// <summary>/// Clears all the pending data to be sent for an AsyncSocket/// </summary>/// <param name="socketModule">The ILibAsyncSocket to clear</param>static void ILibAsyncSocket_ClearPendingSend(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; struct AsyncSocket_SendData *data,*temp; data = module->PendingSend_Head; module->PendingSend_Tail = NULL; while(data!=NULL) { temp = data->Next; if(data->UserFree==0) { // // We only need to free this if we have ownership of this memory // free(data->buffer); } free(data); data = temp; } module->PendingSend_Head = NULL; module->PendingBytesToSend=0;}/// <summary>/// Sends data on an AsyncSocket module/// </summary>/// <param name="socketModule">The ILibAsyncSocket module to send data on</param>/// <param name="buffer">The buffer to send</param>/// <param name="length">The length of the buffer to send</param>/// <param name="ILibAsyncSocket_MemoryOwnership">Flag indicating memory ownership. Refer to ILibAsyncSocket.h for definition of flags</param>/// <returns>0 if send completed, nonzero otherwise. (Usually indicates the send was queued)</returns>int ILibAsyncSocket_Send(void* socketModule, char* buffer, int length, enum ILibAsyncSocket_MemoryOwnership UserFree){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; struct AsyncSocket_SendData *data = (struct AsyncSocket_SendData*)malloc(sizeof(struct AsyncSocket_SendData)); int unblock=0; int bytesSent; data->buffer = buffer; data->bufferSize = length; data->bytesSent = 0; data->UserFree = UserFree; data->Next = NULL; SEM_TRACK(AsyncSocket_TrackLock("ILibAsyncSocket_Send",1,module);) if(module->internalSocket==~0) { // Too Bad, the socket closed if(UserFree==0){free(buffer);} free(data); SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_Send",2,module);) return(ILibAsyncSocket_SEND_ON_CLOSED_SOCKET_ERROR); } module->PendingBytesToSend += length; if(module->PendingSend_Tail!=NULL) { // // There are still bytes that are pending to be sent, so we need to queue this up // module->PendingSend_Tail->Next = data; module->PendingSend_Tail = data; unblock=1; if(UserFree==ILibAsyncSocket_MemoryOwnership_USER) { // // If we don't own this memory, we need to copy the buffer, // because the user may free this memory before we have a chance // to send it // data->buffer = (char*)malloc(data->bufferSize); memcpy(data->buffer,buffer,length); MEMCHECK(assert(length <= data->bufferSize);) data->UserFree = ILibAsyncSocket_MemoryOwnership_CHAIN; } } else { // // There is no data pending to be sent, so lets go ahead and try to send it // module->PendingSend_Tail = data; module->PendingSend_Head = data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -