📄 ilibasyncsocket.c
字号:
/// </summary>/// <param name="readset"></param>/// <param name="writeset"></param>/// <param name="errorset"></param>/// <param name="blocktime"></param>void ILibAsyncSocket_PreSelect(void* socketModule,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; if(module->internalSocket!=-1) { if(module->FinConnect==0) { /* Not Connected Yet */ FD_SET(module->internalSocket,writeset); FD_SET(module->internalSocket,errorset); } else { if(module->PAUSE==0) { /* Already Connected, just needs reading */ FD_SET(module->internalSocket,readset); FD_SET(module->internalSocket,errorset); } } } SEM_TRACK(AsyncSocket_TrackLock("ILibAsyncSocket_PreSelect",1,module);) if(module->PendingSend_Head!=NULL) { // // If there is pending data to be sent, then we need to check when the socket is writable // FD_SET(module->internalSocket,writeset); } SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_PreSelect",2,module);)}/// <summary>/// Chained PostSelect handler for ILibAsyncSocket/// </summary>/// <param name="socketModule"></param>/// <param name="slct"></param>/// <param name="readset"></param>/// <param name="writeset"></param>/// <param name="errorset"></param>void ILibAsyncSocket_PostSelect(void* socketModule,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset){ int TriggerSendOK = 0; struct AsyncSocket_SendData *temp; int bytesSent=0; int flags; struct sockaddr_in receivingAddress; unsigned int receivingAddressLength = sizeof(struct sockaddr_in); struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; int TRY_TO_SEND = 1; // Write Handling if(module->FinConnect!=0 && module->internalSocket!=~0 && FD_ISSET(module->internalSocket,writeset)!=0) { // // The socket is writable, and data needs to be sent // SEM_TRACK(AsyncSocket_TrackLock("ILibAsyncSocket_PostSelect",1,module);) // // Keep trying to send data, until we are told we can't // while(TRY_TO_SEND!=0) { bytesSent = send(module->internalSocket,module->PendingSend_Head->buffer+module->PendingSend_Head->bytesSent,module->PendingSend_Head->bufferSize-module->PendingSend_Head->bytesSent,0); if(bytesSent>0) { module->PendingBytesToSend -= bytesSent; module->TotalBytesSent += bytesSent; module->PendingSend_Head->bytesSent+=bytesSent; if(module->PendingSend_Head->bytesSent==module->PendingSend_Head->bufferSize) { // Finished Sending this block if(module->PendingSend_Head==module->PendingSend_Tail) { module->PendingSend_Tail = NULL; } if(module->PendingSend_Head->UserFree==0) { free(module->PendingSend_Head->buffer); } temp = module->PendingSend_Head->Next; free(module->PendingSend_Head); module->PendingSend_Head = temp; if(module->PendingSend_Head==NULL) {TRY_TO_SEND=0;} } else { // // We sent data, but not everything that needs to get sent was sent, try again // TRY_TO_SEND = 1; } } if(bytesSent==-1) { // Error, clean up everything TRY_TO_SEND = 0; #ifdef _WIN32_WCE bytesSent = WSAGetLastError(); if(bytesSent!=WSAEWOULDBLOCK) #elif defined(WIN32) bytesSent = WSAGetLastError(); if(bytesSent!=WSAEWOULDBLOCK) #else if(errno!=EWOULDBLOCK) #endif { // // There was an error sending // ILibAsyncSocket_ClearPendingSend(socketModule); } } } // // This triggers OnSendOK, if all the pending data has been sent. // if(module->PendingSend_Head==NULL && bytesSent!=-1) {TriggerSendOK=1;} SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_PostSelect",2,module);) if(TriggerSendOK!=0) { module->OnSendOK(module,module->user); } } // // Connection Handling / Read Handling // if(module->internalSocket!=~0) { if(module->FinConnect==0) { /* Not Connected Yet */ if(FD_ISSET(module->internalSocket,writeset)!=0) { /* Connected */ getsockname(module->internalSocket,(struct sockaddr*)&receivingAddress,&receivingAddressLength); module->LocalIPAddress = receivingAddress.sin_addr.s_addr; module->FinConnect = 1; module->PAUSE = 0; // // Set the socket to non-blocking mode, so we can play nice and share the thread // #ifdef _WIN32_WCE flags = 1; ioctlsocket(module->internalSocket,FIONBIO,&flags); #elif defined(WIN32) flags = 1; ioctlsocket(module->internalSocket,FIONBIO,&flags); #elif defined(_POSIX) flags = fcntl(module->internalSocket,F_GETFL,0); fcntl(module->internalSocket,F_SETFL,O_NONBLOCK|flags); #endif /* Connection Complete */ if(module->OnConnect!=NULL) { module->OnConnect(module,-1,module->user); } } if(FD_ISSET(module->internalSocket,errorset)!=0) { /* Connection Failed */ #ifdef _WIN32_WCE closesocket(module->internalSocket); #elif defined(WIN32) closesocket(module->internalSocket); #elif defined(_POSIX) close(module->internalSocket); #endif module->internalSocket = ~0; module->IsFree = 1; if(module->OnConnect!=NULL) { module->OnConnect(module,0,module->user); } } } else { /* Check if PeerReset */ if(FD_ISSET(module->internalSocket,errorset)!=0) { /* Socket Closed */ #ifdef _WIN32_WCE closesocket(module->internalSocket); #elif defined(WIN32) closesocket(module->internalSocket); #elif defined(_POSIX) close(module->internalSocket); #endif module->internalSocket = ~0; module->IsFree=1; module->PAUSE = 1; SEM_TRACK(AsyncSocket_TrackLock("ILibAsyncSocket_PostSelect",3,module);) ILibAsyncSocket_ClearPendingSend(socketModule); SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_PostSelect",4,module);) if(module->OnDisconnect!=NULL) { module->OnDisconnect(module,module->user); } } /* Already Connected, just needs reading */ if(FD_ISSET(module->internalSocket,readset)!=0) { /* Data Available */ ILibProcessAsyncSocket(module); } } }}/// <summary>/// Determines if an ILibAsyncSocket is utilized/// </summary>/// <param name="socketModule">The ILibAsyncSocket to check</param>/// <returns>0 if utilized, nonzero otherwise</returns>int ILibAsyncSocket_IsFree(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; return(module->IsFree);}/// <summary>/// Returns the number of bytes that are pending to be sent/// </summary>/// <param name="socketModule">The ILibAsyncSocket to check</param>/// <returns>Number of pending bytes</returns>unsigned int ILibAsyncSocket_GetPendingBytesToSend(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; return(module->PendingBytesToSend);}/// <summary>/// Returns the total number of bytes that have been sent, since the last reset/// </summary>/// <param name="socketModule">The ILibAsyncSocket to check</param>/// <returns>Number of bytes sent</returns>unsigned int ILibAsyncSocket_GetTotalBytesSent(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; return(module->TotalBytesSent);}/// <summary>/// Resets the total bytes sent counter/// </summary>/// <param name="socketModule">The ILibAsyncSocket to reset</param>void ILibAsyncSocket_ResetTotalBytesSent(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; module->TotalBytesSent = 0;}/// <summary>/// Returns the buffer associated with an ILibAsyncSocket/// </summary>/// <param name="socketModule">The ILibAsyncSocket to obtain the buffer from</param>/// <param name="buffer">The buffer</param>/// <param name="BeginPointer">The BeginPointer</param>/// <param name="EndPointer">The EndPointer</param>void ILibAsyncSocket_GetBuffer(void *socketModule, char **buffer, int *BeginPointer, int *EndPointer){ struct AsyncSocketModule* module = (struct AsyncSocketModule*)socketModule; *buffer = module->buffer; *BeginPointer = module->BeginPointer; *EndPointer = module->EndPointer;}/// <summary>/// Sets the remote address field/// </summary>/// <para>/// This is utilized by the ILibAsyncServerSocket module/// </para>/// <param name="socketModule">The ILibAsyncSocket to modify</param>/// <param name="RemoteAddress">The remote interface</param>void ILibAsyncSocket_SetRemoteAddress(void *socketModule,int RemoteAddress){ struct AsyncSocketModule* module = (struct AsyncSocketModule*)socketModule; module->RemoteIPAddress = RemoteAddress;}/// <summary>/// Associates an actual socket with ILibAsyncSocket/// </summary>/// <para>/// Instead of calling ConnectTo, you can call this method to associate with an already/// connected socket./// </para>/// <param name="socketModule">The ILibAsyncSocket to associate</param>/// <param name="UseThisSocket">The socket to associate</param>/// <param name="InterruptPtr">Function Pointer</param>/// <param name="user"></param>void ILibAsyncSocket_UseThisSocket(void *socketModule,void* UseThisSocket,void (*InterruptPtr)(void *socketModule, void *user),void *user){ #ifdef _WIN32_WCE SOCKET TheSocket = *((SOCKET*)UseThisSocket); #elif defined(WIN32) SOCKET TheSocket = *((SOCKET*)UseThisSocket); #elif defined(_POSIX) int TheSocket = *((int*)UseThisSocket); #endif int flags; struct AsyncSocketModule* module = (struct AsyncSocketModule*)socketModule; module->PendingBytesToSend = 0; module->TotalBytesSent = 0; module->internalSocket = TheSocket; module->IsFree = 0; module->OnInterrupt = InterruptPtr; module->user = user; module->FinConnect = 1; module->PAUSE = 0; // // If the buffer is too small/big, we need to realloc it to the minimum specified size // module->buffer = (char*)realloc(module->buffer,module->InitialSize); module->MallocSize = module->InitialSize; module->FinConnect = 1; module->BeginPointer = 0; module->EndPointer = 0; // // Make sure the socket is non-blocking, so we can play nice and share the thread // #ifdef _WIN32_WCE flags = 1; ioctlsocket(module->internalSocket,FIONBIO,&flags); #elif defined(WIN32) flags = 1; ioctlsocket(module->internalSocket,FIONBIO,&flags); #elif defined(_POSIX) flags = fcntl(module->internalSocket,F_GETFL,0); fcntl(module->internalSocket,F_SETFL,O_NONBLOCK|flags); #endif}/// <summary>/// Returns the Remote Interface of a connected socket/// </summary>/// <param name="socketModule">The ILibAsyncSocket to query</param>/// <returns>The remote interface</returns>int ILibAsyncSocket_GetRemoteInterface(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; return(module->RemoteIPAddress);}/// <summary>/// Returns the Local Interface of a connected socket/// </summary>/// <param name="socketModule">The ILibAsyncSocket to query</param>/// <returns>The local interface</returns>int ILibAsyncSocket_GetLocalInterface(void *socketModule){ struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule; struct sockaddr_in receivingAddress; unsigned int receivingAddressLength = sizeof(struct sockaddr_in); getsockname(module->internalSocket,(struct sockaddr*)&receivingAddress,&receivingAddressLength); return(receivingAddress.sin_addr.s_addr);}/// <summary>/// Resumes a paused session/// </summary>/// <para>/// Sessions can be paused, such that further data is not read from the socket until resumed/// </para>/// <param name="socketModule">The ILibAsyncSocket to resume</param>void ILibAsyncSocket_Resume(void *socketModule){ struct AsyncSocketModule *sm = (struct AsyncSocketModule*)socketModule; if(sm->PAUSE!=0) { sm->PAUSE=0; ILibForceUnBlockChain(sm->Chain); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -