⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ilibasyncsocket.c

📁 intel upnp stack source code
💻 C
📖 第 1 页 / 共 3 页
字号:
				bytesSent = send(module->internalSocket,module->PendingSend_Head->buffer+module->PendingSend_Head->bytesSent,module->PendingSend_Head->bufferSize-module->PendingSend_Head->bytesSent,0);		if(bytesSent>0)		{			//			// We were able to send something, so lets increment the counters			//			module->PendingSend_Head->bytesSent+=bytesSent;			module->PendingBytesToSend -= bytesSent;			module->TotalBytesSent += bytesSent;		}		if(bytesSent==-1)		{			// 			// Send returned an error, so lets figure out what it was,			// as it could be normal			//#ifdef _WIN32_WCE			bytesSent = WSAGetLastError();			if(bytesSent!=WSAEWOULDBLOCK)#elif defined(WIN32)			bytesSent = WSAGetLastError();			if(bytesSent!=WSAEWOULDBLOCK)#else			if(errno!=EWOULDBLOCK)#endif			{				//				// Most likely the socket closed while we tried to send				//				if(UserFree==0){free(buffer);}				module->PendingSend_Head = module->PendingSend_Tail = NULL;				free(data);				SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_Send",3,module);)								//				//Ensure Calling On_Disconnect with MicroStackThread				//				ILibLifeTime_Add(module->LifeTime,socketModule,0,&ILibAsyncSocket_Disconnect,NULL);								return(ILibAsyncSocket_SEND_ON_CLOSED_SOCKET_ERROR);			}		}		if(module->PendingSend_Head->bytesSent==module->PendingSend_Head->bufferSize)		{			//			// All of the data has been sent			//			if(UserFree==0){free(module->PendingSend_Head->buffer);}			module->PendingSend_Tail = NULL;			free(module->PendingSend_Head);			module->PendingSend_Head = NULL;		}		else		{			//			// All of the data wasn't sent, so we need to copy the buffer			// if we don't own the memory, because the user may free the			// memory, before we have a chance to complete sending it.			//			if(UserFree==ILibAsyncSocket_MemoryOwnership_USER)			{				data->buffer = (char*)malloc(data->bufferSize);				memcpy(data->buffer,buffer,length);				MEMCHECK(assert(length <= data->bufferSize);)				data->UserFree = ILibAsyncSocket_MemoryOwnership_CHAIN;			}			unblock = 1;		}	}	SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_Send",4,module);)	if(unblock!=0) {ILibForceUnBlockChain(module->Chain);}	return(unblock);}/// <summary>/// Disconnects an ILibAsyncSocket/// </summary>/// <param name="socketModule">The ILibAsyncSocket to disconnect</param>void ILibAsyncSocket_Disconnect(void* socketModule){	#ifdef _WIN32_WCE		SOCKET s;	#elif defined(WIN32)		SOCKET s;	#elif defined(_POSIX)		int s;	#endif	struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule;	if (module == NULL)		return;	SEM_TRACK(AsyncSocket_TrackLock("ILibAsyncSocket_Disconnect",1,module);)		if(module->internalSocket!=~0)	{		//		// There is an associated socket that is still valid, so we need to close it		//		module->IsFree = 1;		module->PAUSE = 1;		s = module->internalSocket;		module->internalSocket = ~0;		if(s!=-1)		{			#ifdef _WIN32_WCE					closesocket(s);			#elif defined(WIN32)					closesocket(s);			#elif defined(_POSIX)					close(s);			#endif		}		//		// Since the socket is closing, we need to clear the data that is pending to be sent		//		ILibAsyncSocket_ClearPendingSend(socketModule);		SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_Disconnect",2,module);)		if(module->OnDisconnect!=NULL)		{			//			// Trigger the OnDissconnect event if necessary			//			module->OnDisconnect(module,module->user);		}	}	else	{		SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_Disconnect",3,module);)	}}/// <summary>/// Attempts to establish a TCP connection/// </summary>/// <param name="socketModule">The ILibAsyncSocket to initiate the connection</param>/// <param name="localInterface">The interface to use to establish the connection</param>/// <param name="remoteInterface">The remote interface to connect to</param>/// <param name="remotePortNumber">The remote port to connect to</param>/// <param name="InterruptPtr">Function Pointer that triggers if connection attempt is interrupted</param>/// <param name="user">User object that will be passed to the OnConnect method</param>void ILibAsyncSocket_ConnectTo(void* socketModule, int localInterface, int remoteInterface, int remotePortNumber, void (*InterruptPtr)(void *socketModule, void *user),void *user){	int flags;	struct sockaddr_in addr;	struct AsyncSocketModule *module = (struct AsyncSocketModule*)socketModule;		module->PendingBytesToSend = 0;	module->TotalBytesSent = 0;	module->IsFree = 0;	module->PAUSE = 0;	module->user = user;	module->OnInterrupt = InterruptPtr;	module->buffer = (char*)realloc(module->buffer,module->InitialSize);	module->MallocSize = module->InitialSize;	memset((char *)&addr, 0,sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_addr.s_addr = remoteInterface;	#ifdef _WIN32_WCE		addr.sin_port = htons((unsigned short)remotePortNumber);	#elif defined(WIN32)		addr.sin_port = htons(remotePortNumber);	#elif defined(_POSIX)		addr.sin_port = htons(remotePortNumber);	#endif		//	// If there isn't a socket already allocated, we need to allocate one	//	if(module->internalSocket==-1)	{		#ifdef WINSOCK2			ILibGetStreamSocket(localInterface,0,(HANDLE*)&(module->internalSocket));		#else			ILibGetStreamSocket(localInterface,0,&(module->internalSocket));		#endif	}		//	// Initialise the buffer pointers, since no data is in them yet.	//	module->FinConnect = 0;	module->BeginPointer = 0;	module->EndPointer = 0;		//	// Set the socket to non-blocking mode, because we need to play nice	// and share the MicroStack 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	//	// Connect the socket, and force the chain to unblock, since the select statement	// doesn't have us in the fdset yet.	//	connect(module->internalSocket,(struct sockaddr*)&addr,sizeof(addr));	ILibForceUnBlockChain(module->Chain);}/// <summary>/// Internal method called when data is ready to be processed on an ILibAsyncSocket/// </summary>/// <param name="Reader">The ILibAsyncSocket with pending data</param>static void ILibProcessAsyncSocket(struct AsyncSocketModule *Reader){	int bytesReceived;	char *temp;	//	// If the thing isn't paused, and the user set the pointers such that we still have data	// in our buffers, we need to call the user back with that data, before we attempt to read	// more data off the network	//	while(Reader->PAUSE==0 && Reader->BeginPointer!=Reader->EndPointer && Reader->BeginPointer!=0)	{		memmove(Reader->buffer,Reader->buffer+Reader->BeginPointer,Reader->EndPointer-Reader->BeginPointer);		MEMCHECK(assert(Reader->EndPointer-Reader->BeginPointer <= Reader->MallocSize);)				Reader->EndPointer = Reader->EndPointer-Reader->BeginPointer;		Reader->BeginPointer = 0;		if(Reader->OnData!=NULL)		{			Reader->OnData(Reader,Reader->buffer,&(Reader->BeginPointer),Reader->EndPointer,&(Reader->OnInterrupt),&(Reader->user),&(Reader->PAUSE));		}	}	if(Reader->PAUSE!=0)	{		return;	}		/* Reading Body Only */	if(Reader->BeginPointer == Reader->EndPointer)	{		Reader->BeginPointer = 0;		Reader->EndPointer = 0;	}	else	{		if(Reader->BeginPointer!=0)		{			Reader->EndPointer = Reader->BeginPointer;		}	}		bytesReceived = recv(Reader->internalSocket,Reader->buffer+Reader->EndPointer,Reader->MallocSize-Reader->EndPointer,0);		if(bytesReceived<=0)	{		//		// This means the socket was gracefully closed by the remote endpoint		//		Reader->IsFree = 1;		SEM_TRACK(AsyncSocket_TrackLock("ILibProcessAsyncSocket",1,Reader);)		ILibAsyncSocket_ClearPendingSend(Reader);		SEM_TRACK(AsyncSocket_TrackUnLock("ILibProcessAsyncSocket",2,Reader);)		#ifdef _WIN32_WCE			closesocket(Reader->internalSocket);		#elif defined(WIN32)			closesocket(Reader->internalSocket);		#elif defined(_POSIX)			close(Reader->internalSocket);		#endif		Reader->internalSocket = ~0;		Reader->IsFree = 1;		//		// Inform the user the socket has closed		//		if(Reader->OnDisconnect!=NULL)		{			Reader->OnDisconnect(Reader,Reader->user);		}		//		// If we need to free the buffer, do so		//		if(Reader->IsFree!=0 && Reader->buffer!=NULL)		{			free(Reader->buffer);			Reader->buffer = NULL;			Reader->MallocSize = 0;		}	}	else	{		//		// Data was read, so increment our counters		//		Reader->EndPointer += bytesReceived;		//		// Tell the user we have some data		//		if(Reader->OnData!=NULL)		{			Reader->OnData(Reader,Reader->buffer,&(Reader->BeginPointer),Reader->EndPointer,&(Reader->OnInterrupt),&(Reader->user),&(Reader->PAUSE));		}		//		// If the user set the pointers, and we still have data, call them back with the data		//		while(Reader->PAUSE==0 && Reader->BeginPointer!=Reader->EndPointer && Reader->BeginPointer!=0)		{			memmove(Reader->buffer,Reader->buffer+Reader->BeginPointer,Reader->EndPointer-Reader->BeginPointer);			MEMCHECK(assert(Reader->EndPointer-Reader->BeginPointer <= Reader->MallocSize);)						Reader->EndPointer = Reader->EndPointer-Reader->BeginPointer;			Reader->BeginPointer = 0;			if(Reader->OnData!=NULL)			{				Reader->OnData(Reader,Reader->buffer,&(Reader->BeginPointer),Reader->EndPointer,&(Reader->OnInterrupt),&(Reader->user),&(Reader->PAUSE));			}		}				//		// If the user consumed all of the buffer, we can recycle it		//		if(Reader->BeginPointer==Reader->EndPointer)		{			Reader->BeginPointer = 0;			Reader->EndPointer = 0;		}				//		// If we need to grow the buffer, do it now		//		if(Reader->MallocSize - Reader->EndPointer <1024)		{			//			// This memory reallocation sometimes causes Insure++			// to incorrectly report a READ_DANGLING (usually in 			// a call to ILibWebServer_StreamHeader_Raw.)			// 			// We verified that the problem is with Insure++ by			// noting the value of 'temp' (0x008fa8e8), 			// 'Reader->buffer' (0x00c55e80), and			// 'MEMORYCHUNKSIZE' (0x00001800).			//			// When Insure++ reported the error, it (incorrectly) 			// claimed that a pointer to memory address 0x00c55ea4			// was invalid, while (correctly) citing the old memory			// (0x008fa8e8-0x008fb0e7) as freed memory.			// Normally Insure++ reports that the invalid pointer 			// is pointing to someplace in the deallocated block,			// but that wasn't the case.			//			Reader->MallocSize += MEMORYCHUNKSIZE;			temp = Reader->buffer;			Reader->buffer = (char*)realloc(Reader->buffer,Reader->MallocSize);			//			// If this realloc moved the buffer somewhere, we need to inform people of it			//			if(Reader->buffer!=temp && Reader->OnBufferReAllocated!=NULL)			{				Reader->OnBufferReAllocated(Reader,Reader->user,Reader->buffer-temp);			}		}	}}void * ILibAsyncSocket_GetUser(void *socketModule){	return(((struct AsyncSocketModule*)socketModule)->user);}/// <summary>/// Chained PreSelect handler for ILibAsyncSocket

⌨️ 快捷键说明

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