void ILibAsyncServerSocket_PreSelect(void * socketModule, void *readset, void *writeset, void *errorset, int* blocktime) { struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule; int flags, i; // 没有开始监听 if (module->listening == 0) { // Set the socket to non-block mode, so we can play nice and share the thread #ifdef _WIN32_WCE flags = 1; ioctlsocket(module->ListenSocket,FIONBIO,&flags); #elif WIN32 flags = 1; ioctlsocket(module->ListenSocket, FIONBIO, &flags); #elif _POSIX flags = fcntl(module->ListenSocket,F_GETFL,0); fcntl(module->ListenSocket,F_SETFL,O_NONBLOCK|flags); #endif // Put the socket in Listen, and add it to the fdset for the Select loop module->listening = 1; listen(module->ListenSocket, 4); FD_SET(module->ListenSocket, (fd_set*)readset); } else { // Only put the ListenSocket in the readset, if we are able to handle a new socket for (i = 0; i < module->MaxConnection; ++i) { if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0) { FD_SET(module->ListenSocket, (fd_set*)readset); break; } } } }
void ILibAsyncServerSocket_PreSelect(void* socketModule,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime) { struct AsyncServerSocketModule *module = (struct AsyncServerSocketModule*)socketModule; int flags,i; if(module->listening==0) { #ifdef _WIN32_WCE flags = 1; ioctlsocket(module->ListenSocket,FIONBIO,&flags); #elif WIN32 flags = 1; ioctlsocket(module->ListenSocket,FIONBIO,&flags); #elif _POSIX flags = fcntl(module->ListenSocket,F_GETFL,0); fcntl(module->ListenSocket,F_SETFL,O_NONBLOCK|flags); #endif module->listening=1; listen(module->ListenSocket,4); FD_SET(module->ListenSocket,readset); } else { // Only put the ListenSocket in the readset, if we are able to handle a new socket for(i=0;i<module->MaxConnection;++i) { if(ILibAsyncSocket_IsFree(module->AsyncSockets[i])!=0) { FD_SET(module->ListenSocket,readset); break; } } } }
void ILibWebServer_IdleSink(void *object) { struct ILibWebServer_Session *session = (struct ILibWebServer_Session*)object; if(ILibAsyncSocket_IsFree(session->Reserved2)==0) { ILibAsyncServerSocket_Disconnect(session->Reserved1,session->Reserved2); } }
void ILibAsyncServerSocket_PostSelect(void* socketModule,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset) { struct AsyncServerSocket_Data *data; struct sockaddr_in addr; int addrlen; struct AsyncServerSocketModule *module = (struct AsyncServerSocketModule*)socketModule; int i,flags; #ifdef _WIN32_WCE SOCKET NewSocket; #elif WIN32 SOCKET NewSocket; #elif _POSIX int NewSocket; #endif if(FD_ISSET(module->ListenSocket,readset)!=0) { for(i=0;i<module->MaxConnection;++i) { if(ILibAsyncSocket_IsFree(module->AsyncSockets[i])!=0) { addrlen = sizeof(addr); NewSocket = accept(module->ListenSocket,(struct sockaddr*)&addr,&addrlen); if (NewSocket != ~0) { #ifdef _WIN32_WCE flags = 1; ioctlsocket(NewSocket,FIONBIO,&flags); #elif WIN32 flags = 1; ioctlsocket(NewSocket,FIONBIO,&flags); #elif _POSIX flags = fcntl(NewSocket,F_GETFL,0); fcntl(NewSocket,F_SETFL,O_NONBLOCK|flags); #endif data = (struct AsyncServerSocket_Data*)MALLOC(sizeof(struct AsyncServerSocket_Data)); data->module = socketModule; data->user = NULL; ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i],&NewSocket,&ILibAsyncServerSocket_OnInterrupt,data); ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i],addr.sin_addr.s_addr); if(module->OnConnect!=NULL) { module->OnConnect(module,module->AsyncSockets[i],&(data->user)); } } else {break;} } } } }
void ILibAsyncServerSocket_OnData(ILibAsyncSocket_SocketModule socketModule,char* buffer,int *p_beginPointer, int endPointer,void (**OnInterrupt)(void *AsyncSocketMoudle, void *user),void **user, int *PAUSE) { struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)(*user); int bpointer = *p_beginPointer; // Pass the received data up if (data != NULL && data->module->OnReceive != NULL) { data->module->OnReceive(data->module,socketModule,buffer,&bpointer,endPointer,&(data->module->OnInterrupt),&(data->user),PAUSE); if (ILibAsyncSocket_IsFree(socketModule)) { *p_beginPointer = endPointer; } else { *p_beginPointer = bpointer; } } }
void ILibAsyncServerSocket_PostSelect(void* socketModule,int slct, void *readset, void *writeset, void *errorset) { struct ILibAsyncServerSocket_Data *data; struct sockaddr_in addr; int addrlen; struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule; int i,flags; struct sockaddr_in receivingAddress; int receivingAddressLength = sizeof(struct sockaddr_in); #ifdef _WIN32_WCE SOCKET NewSocket; #elif WIN32 SOCKET NewSocket; #elif defined( _POSIX) int NewSocket; #endif if (FD_ISSET(module->ListenSocket,(fd_set*)readset) != 0) { // There are pending TCP connection requests for (i = 0; i < module->MaxConnection; ++i) { // Check to see if we have available resources to handle this connection request if(ILibAsyncSocket_IsFree(module->AsyncSockets[i])!=0) { addrlen = sizeof(addr); NewSocket = accept(module->ListenSocket, (struct sockaddr*)&addr ,&addrlen); if (NewSocket != ~0) { switch(module->scope) { case ILibServerScope_LocalLoopback: // Check that the caller ip address is the same as the receive IP address getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength); if(receivingAddress.sin_addr.s_addr != addr.sin_addr.s_addr) { #if defined(WIN32) || defined(_WIN32_WCE) closesocket(NewSocket); #else close(NewSocket); #endif NewSocket = ~0; } break; case ILibServerScope_LocalSegment: getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength); break; default: break; } } if (NewSocket != ~0) { // Set this new socket to non-blocking mode, so we can play nice and share thread #ifdef _WIN32_WCE flags = 1; ioctlsocket(NewSocket,FIONBIO,&flags); #elif WIN32 flags = 1; ioctlsocket(NewSocket,FIONBIO,&flags); #elif _POSIX flags = fcntl(NewSocket,F_GETFL,0); fcntl(NewSocket,F_SETFL,O_NONBLOCK|flags); #endif // Instantiate a module to contain all the data about this connection data = (struct ILibAsyncServerSocket_Data*)malloc(sizeof(struct ILibAsyncServerSocket_Data)); memset(data,0,sizeof(struct ILibAsyncServerSocket_Data)); data->module = socketModule; ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i], &NewSocket, &ILibAsyncServerSocket_OnInterruptSink, data); ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i],addr.sin_addr.s_addr); // Notify the user about this new connection if (module->OnConnect != NULL) { module->OnConnect(module,module->AsyncSockets[i], &(data->user)); } } else { break; } } } } }
// // Chain PostSelect handler // // <param name="socketModule"></param> // <param name="slct"></param> // <param name="readset"></param> // <param name="writeset"></param> // <param name="errorset"></param> void ILibAsyncServerSocket_PostSelect(void* socketModule, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset) { struct ILibAsyncServerSocket_Data *data; struct sockaddr_in6 addr; //struct sockaddr_in6 receivingAddress; #ifdef _POSIX socklen_t addrlen; //socklen_t receivingAddressLength = sizeof(struct sockaddr_in6); #else int addrlen; //int receivingAddressLength = sizeof(struct sockaddr_in6); #endif struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule; int i,flags; #ifdef _WIN32_WCE SOCKET NewSocket; #elif WIN32 SOCKET NewSocket; #elif defined( _POSIX) int NewSocket; #endif UNREFERENCED_PARAMETER( slct ); UNREFERENCED_PARAMETER( writeset ); UNREFERENCED_PARAMETER( errorset ); if (FD_ISSET(module->ListenSocket, readset) != 0) { // // There are pending TCP connection requests // for(i = 0; i < module->MaxConnection; ++i) { // // Check to see if we have available resources to handle this connection request // if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0) { addrlen = sizeof(addr); NewSocket = accept(module->ListenSocket, (struct sockaddr*)&addr, &addrlen); //printf("Accept NewSocket=%d\r\n", NewSocket); // This code rejects connections that are from out-of-scope addresses (Outside the subnet, outside local host...) // It needs to be updated to IPv6. /* if (NewSocket != ~0) { switch(module->scope) { case ILibServerScope_LocalLoopback: // Check that the caller ip address is the same as the receive IP address getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength); if (((struct sockaddr_in*)&receivingAddress)->sin_addr.s_addr != ((struct sockaddr_in*)&addr)->sin_addr.s_addr) // TODO: NOT IPv6 COMPILANT!!!!!!!!!!!!!!!!!!!!!!!! { #if defined(WIN32) || defined(_WIN32_WCE) closesocket(NewSocket); #else close(NewSocket); #endif NewSocket = ~0; } break; case ILibServerScope_LocalSegment: getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength); break; default: break; } } */ if (NewSocket != ~0) { //printf("Accepting new connection, socket = %d\r\n", NewSocket); // // Set this new socket to non-blocking mode, so we can play nice and share thread // #ifdef _WIN32_WCE flags = 1; ioctlsocket(NewSocket ,FIONBIO, &flags); #elif WIN32 flags = 1; ioctlsocket(NewSocket, FIONBIO, (u_long *)(&flags)); #elif _POSIX flags = fcntl(NewSocket, F_GETFL,0); fcntl(NewSocket, F_SETFL, O_NONBLOCK|flags); #endif // // Instantiate a module to contain all the data about this connection // if ((data = (struct ILibAsyncServerSocket_Data*)malloc(sizeof(struct ILibAsyncServerSocket_Data))) == NULL) ILIBCRITICALEXIT(254); memset(data, 0, sizeof(struct ILibAsyncServerSocket_Data)); data->module = socketModule; ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i], &NewSocket, &ILibAsyncServerSocket_OnInterruptSink, data); ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i], (struct sockaddr*)&addr); #ifndef MICROSTACK_NOTLS if (module->ssl_ctx != NULL) { // Accept a new TLS connection ILibAsyncSocket_SetSSLContext(module->AsyncSockets[i], module->ssl_ctx, 1); } else #endif if (module->OnConnect != NULL) { // Notify the user about this new connection module->OnConnect(module, module->AsyncSockets[i], &(data->user)); } } else {break;} } } } }
// // Chain PreSelect handler // // <param name="socketModule"></param> // <param name="readset"></param> // <param name="writeset"></param> // <param name="errorset"></param> // <param name="blocktime"></param> void ILibAsyncServerSocket_PreSelect(void* socketModule, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime) { struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule; int flags,i; UNREFERENCED_PARAMETER( writeset ); UNREFERENCED_PARAMETER( errorset ); UNREFERENCED_PARAMETER( blocktime ); // // The socket isn't put in listening mode, until the chain is started. // If this variable == 0, that means we need to do that. // if (module->listening == 0) { // // Set the socket to non-block mode, so we can play nice and share the thread // #ifdef _WIN32_WCE flags = 1; ioctlsocket(module->ListenSocket, FIONBIO, &flags); #elif WIN32 flags = 1; ioctlsocket(module->ListenSocket, FIONBIO, (u_long *)(&flags)); #elif _POSIX flags = fcntl(module->ListenSocket, F_GETFL,0); fcntl(module->ListenSocket, F_SETFL, O_NONBLOCK | flags); #endif // // Put the socket in Listen, and add it to the fdset for the Select loop // module->listening = 1; listen(module->ListenSocket, 4); #if defined(WIN32) #pragma warning( push, 3 ) // warning C4127: conditional expression is constant #endif FD_SET(module->ListenSocket, readset); #if defined(WIN32) #pragma warning( pop ) #endif } else { // Only put the ListenSocket in the readset, if we are able to handle a new socket for(i = 0; i < module->MaxConnection; ++i) { if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0) { #if defined(WIN32) #pragma warning( push, 3 ) // warning C4127: conditional expression is constant #endif FD_SET(module->ListenSocket, readset); #if defined(WIN32) #pragma warning( pop ) #endif break; } } } }
// // An internal method called by Chain as Destroy, to cleanup AsyncSocket // // <param name="socketModule">The AsyncSocketModule</param> void ILibAsyncSocket_Destroy(void *socketModule) { struct ILibAsyncSocketModule* module = (struct ILibAsyncSocketModule*)socketModule; struct ILibAsyncSocket_SendData *temp,*current; // // Call the interrupt event if necessary // if(!ILibAsyncSocket_IsFree(module)) { if(module->OnInterrupt!=NULL) { module->OnInterrupt(module,module->user); } } // // Close socket if necessary // if(module->internalSocket!=~0) { #if defined(_WIN32_WCE) || defined(WIN32) #if defined(WINSOCK2) shutdown(module->internalSocket,SD_BOTH); #endif closesocket(module->internalSocket); #elif defined(_POSIX) shutdown(module->internalSocket,SHUT_RDWR); close(module->internalSocket); #endif } // // 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; } sem_destroy(&(module->SendLock)); }