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

📄 tcpipsck.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#if POSIX
			if ( errno==EINTR )	{ /* just a signal */ continue; };
			if ( errno==ECONNRESET ) { /* aborted connection */ continue; };
#endif
			};

		/* --- done --- */
		break;
		};

	/* --- NULL out the pointer to pNewSocket --- */
	pAcceptingIOObject = 0;

	if ( iNewS<0 ) 
		{
		return PIAPI_ERROR; /* non-critical error, callee may try again */
		};
	pChildData->iSocket=iNewS;

	/* ---
	**
	**
	** This is a new connection. Look at the flags and variable names
	** to see what lookups should occur and where the data is put
	**
	**
	--- */

	/* --- should this object set the PeerIP address? --- */
	int iFlags = pChildData->pMainSocketData->iFlags;

	/* ---
	Set PeerAddress variable, if applicable
	--- */
	/* ---
	When the hostname is unavailable just have it turn up blank
#	define TEXT_UNAVAILABLE	"** Unavailable **"
	--- */
#	define TEXT_UNAVAILABLE	""

	if ( iFlags & FLG_SETREMOTEADDRESS )
		{
		/* --- set remote Address ? --- */
		DBInfo *pIPInfo = pChildData->pMainSocketData->pPeerAddressVariable;
		if ( pIPInfo )
			{
			/* ---
			inet_ntoa is not thread safe, protect access to it
			--- */
			PIPlatform_beforeUnsafeBlock();

			/* --- convert the peer ip to a string if we have the ip --- */
			const char *pPeerAddress = 0;
			pPeerAddress = ::inet_ntoa( pChildData->tAddr.sin_addr );

			PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType,
				pIPInfo->pFKVariableName, (void *)pPeerAddress,
				pIPInfo->iFlags | PIDBFLAG_FASTKEY );
			PIPlatform_afterUnsafeBlock();
			};

		if ( iFlags & FLG_DNSREVERSELOOKUP )
			{
			/* --- set remote hostname ? --- */
			DBInfo *pHostInfo = pChildData->pMainSocketData->pPeerHostVariable;
			if ( pHostInfo )
				{
				/* ---
				inet_ntoa is not thread safe, protect access to it
				--- */
				PIPlatform_beforeUnsafeBlock();

				/* --- if we have the ip structure, lookup the hostname --- */
				struct hostent *pEnt;
				pEnt = ::gethostbyaddr(
					(const char *)&(pChildData->tAddr.sin_addr),
					sizeof(pChildData->tAddr.sin_addr), AF_INET ); 
				PIDB_add( PIObject_getDB( pNewSocket ), pHostInfo->iType,
					pHostInfo->pFKVariableName,
					(void *)( pEnt ? pEnt->h_name : TEXT_UNAVAILABLE ),
					pHostInfo->iFlags | PIDBFLAG_FASTKEY ); 
				PIPlatform_afterUnsafeBlock();
				};
			};
		};

	/* ---
	Set LocalAddress if applicable
	--- */
	if ( iFlags & FLG_SETLOCALADDRESS )
		{
		DBInfo *pIPInfo = pChildData->pMainSocketData->pLocalAddressVariable;
		if ( pIPInfo )
			{
			struct sockaddr_in tLocalAddr;
			int iLocalSize = sizeof( struct sockaddr_in );

			for(;;)
				{
				/* --- get local socket information --- */
				if ( ::getsockname( pChildData->iSocket,
						(struct sockaddr *)&tLocalAddr,
						&((uint)iLocalSize) )==-1 )
					{
					if ( errno==EINTR )
						{
						/* --- restart system call --- */
						PIThread_userYield();
						continue;
						};
					iLocalSize = 0;	/* indicate an error */
					};
				break;
				};

			if ( iLocalSize>0 )
				{
				/* ---
				inet_ntoa is not thread safe, protect access to it
				--- */
				PIPlatform_beforeUnsafeBlock();
	
				const char *pLocalAddress = 0;
	
				pLocalAddress = ::inet_ntoa( tLocalAddr.sin_addr );
				PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType,
					pIPInfo->pFKVariableName, (void *)pLocalAddress,
					pIPInfo->iFlags | PIDBFLAG_FASTKEY );

				/* ---
				set ServerPort variable
				--- */
				DBInfo *pIPInfo = pChildData->pMainSocketData->pServerPortVariable;
				if ( pIPInfo ) {
					int localPort = ntohs (tLocalAddr.sin_port);
					char szPort[6];
					char *pPort = szPort;
					sprintf(pPort, "%lu", localPort);
					PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType, pIPInfo->pFKVariableName,
						(void *)pPort, 0 );
				};

				PIPlatform_afterUnsafeBlock();
				}
			else
				{
				/* --- error --- */
				STDERR << "getsockname() failed, errno#" << errno << endl;
				PIDB_add( PIObject_getDB( pNewSocket ), pIPInfo->iType,
					pIPInfo->pFKVariableName, (void *)"0.0.0.0",
					pIPInfo->iFlags | PIDBFLAG_FASTKEY );
				};	/* iLocalSize!=0 */

			};	/* pIPInfo!=NULL */
		};	/* iFlags & FLG_SETLOCALADDRRESS */

	/* ---
	Write send and receive timeout into the DB, to be overridden as
	necessary
	--- */
	assert( pFKRecvTimeout );
	assert( pFKSendTimeout );
	PIDB_add( PIObject_getDB( pNewSocket ), PIDBTYPE_OPAQUE, pFKRecvTimeout,
		(void *)(pChildData->pMainSocketData->iRecvTimeout), PIDBFLAG_FASTKEY );
	PIDB_add( PIObject_getDB( pNewSocket ), PIDBTYPE_OPAQUE, pFKSendTimeout,
		(void *)(pChildData->pMainSocketData->iSendTimeout), PIDBFLAG_FASTKEY );

	/* ---
	Done
	--- */
	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:		 TCPIPSocket_onClassLoad
 Synopsis:
 Description:
	This is called on program startup, restart or shutdown.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int TCPIPSocket_onClassLoad( PIClass_LoadAction eAction,
	void * /* pV */ )
{
#if WIN32
	WSAData tWSAData;
	enum { DESIRED_WINSOCK_VERSION=0x0101 };
	/* enum { DESIRED_WINSOCK_VERSION=0x0200 }; */
#endif

	switch( eAction )
		{
		case STARTUP:
#if WIN32
			/*
			** WSAStartup returns 0 or one of these values
			**
			WSASYSNOTREADY
			WSAVERNOTSUPPORTED
			WSAEINVAL
			*/
			if ( ::WSAStartup( DESIRED_WINSOCK_VERSION, &tWSAData ) )
				{ return PIAPI_ABORT; };
#endif

			/* ---
			Get fast keys
			--- */
			pFKSendTimeout = PIDB_getFastKey( KEY_CONF_SENDTIMEOUT, 
				PIDBTYPE_OPAQUE );
			pFKRecvTimeout = PIDB_getFastKey( KEY_CONF_RECVTIMEOUT, 
				PIDBTYPE_OPAQUE );
			break;

		case SHUTDOWN:
#if WIN32
			WSACleanup();
#endif
			break;
		
		default:;
		};

	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:		 TCPIPSocket_TCPIPSocket
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int TCPIPSocket_TCPIPSocket(
	PIObject *pObject,
	int iArgc,
	const char *ppArgv[]
	)
{
	/*
	** Allocate instance data
	*/
	TCPIPSocketData *pData = new TCPIPSocketData( pObject, iArgc, ppArgv );	
	PIObject_setUserData( pObject, pData );

	/*
	*/
	/* --- pObject is the new parent socket --- */
	if ( !pData->IsOK() )
		{ return PIAPI_ABORT; };

	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:		 TCPIPSocket_copyTCPIPSocket
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int TCPIPSocket_copyTCPIPSocket( PIObject *pObject, int iArgc,
	const char *ppArgv[] )
{
	/* automatic variables */
	TCPIPSocketData *pData;
	TCPIPSocketData *pParentData;

	/*
	** Grap old user data, as pParentData
	*/
	pParentData = (TCPIPSocketData *)PIObject_getUserData( pObject ); 

	/*
	** Allocate instance data
	*/
	pData = new TCPIPSocketData( pObject, pParentData, iArgc, ppArgv );

	/* ---
	Is this an active or passive socket?
	--- */
	if ( pData->pMainSocketData->iServer )
		{
		/* --- 
		Attempt to accept a new connection on pObject socket
		--- */
		int iRet = pData->pMainSocketData->Accept( pParentData, pObject );
		if ( iRet!=PIAPI_COMPLETED )
			{ return iRet; };
		}
	else
		{
		/* --- 
		Attempt to make a new connection to a remote host
		--- */
		const char *pHostName;
		int iPort;

		/* --- 
		If not given as arguments connect to the remote host
		with parameters found in the main socket data
		--- */
		if ( iArgc!=2 )
		    {
		    pHostName = pData->pMainSocketData->pHost;
		    iPort = pData->pMainSocketData->iPort;
		    }
		else
		    {
		    pHostName = (const char *)ppArgv[0];
		    iPort = (int)ppArgv[1];
		    };
		    
		if ( Internal_connect( pObject, pHostName, iPort ) )
			{
			return PIAPI_ERROR;
			};
		};

	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:		TCPIPSocket_xTCPIPSocket
 Synopsis:
 Description:
	Destructor for instances of the TCPIPSocket class. Performs cleanup.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int TCPIPSocket_xTCPIPSocket( PIObject *pObject, int,
	const char *[] )
{
	delete (TCPIPSocketData *)PIObject_getUserData( pObject );
	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:	   TCPIPSocket_send
 Synopsis:
 Description:
	Send data down pObject socket.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int TCPIPSocket_send( PIObject *pObject, void *pData,
	int iLen, int *piSent, int, const char *[] )
{
	/* --- automatic variables --- */
	int iRet = -1;
	int iToSend=iLen;
	int iSent=0;
	const char *pToSend=(const char *)pData;
	TCPIPSocketData *pInstanceData=
	(TCPIPSocketData *)PIObject_getUserData( pObject );
	assert( pToSend && pInstanceData && iToSend && piSent );

	int iTimeout=(int)PIDB_lookup( PIObject_getDB( pObject ),
		PIDBTYPE_OPAQUE, pFKSendTimeout, PIDBFLAG_FASTKEY );
	do	{	
		if ( PIPlatform_pollNetFD( pInstanceData->iSocket,
			PIPLATFORM_POLL_WRITE, 
			iTimeout ) <=0 )
			{ break; };
		iRet=send( pInstanceData->iSocket, &(pToSend[iSent]), iToSend, 0 ); 
		if ( !iRet ) break;							/* connection closed */
		if ( iRet==-1 )
			{
			if ( errno==EINTR )
				{ continue;	/* signal caught */ };

			break;
			};
		iSent += iRet;
		iToSend -= iRet;
		} 
	while( iToSend>0 ); 
	
	if ( iRet==-1 )
		{ return PIAPI_ERROR; };
	*piSent=iSent;
	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:	   TCPIPSocket_recv
 Synopsis:
 Description:
	Get data out of pObject socket.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int TCPIPSocket_recv( PIObject *pObject, void *pData,
	int iLen, int *piReceived, int, const char *[] )
{
	/* --- automatic variables --- */
	int iRet = -1;
	TCPIPSocketData *pInstanceData=
		(TCPIPSocketData *)PIObject_getUserData( pObject );
	assert( pInstanceData && piReceived );

	int iTimeout=(int)PIDB_lookup( PIObject_getDB( pObject ),
		PIDBTYPE_OPAQUE, pFKRecvTimeout, PIDBFLAG_FASTKEY );
	for(;;)
		{	
		if ( PIPlatform_pollNetFD( pInstanceData->iSocket,
			PIPLATFORM_POLL_READ, 
			iTimeout ) <=0 )
			{ break; };

		iRet=::recv( pInstanceData->iSocket, (char *)pData, iLen, 0 ); 
		if ( iRet==-1 && errno==EINTR ) continue;	/* signal caught */
		break;
		}; 
	
	if ( iRet==-1 ) return PIAPI_ERROR;
	*piReceived=iRet;
	return PIAPI_COMPLETED;
}

/* ---
	Class configuration specification 
--- */
#if 0
/*___+++CNF_BEGIN+++___*/
	<Class>
		Name TCPIPIOClass
		Type IO
		Library IO
		OnClassLoad TCPIPSocket_onClassLoad
		Constructor TCPIPSocket_TCPIPSocket
		CopyConstructor TCPIPSocket_copyTCPIPSocket
		Destructor TCPIPSocket_xTCPIPSocket
		Out TCPIPSocket_send
		In TCPIPSocket_recv
	</Class>

	<Object>
		Name TCPIO
		Class TCPIPIOClass
		Type Passive
		AcceptTimeout -1
		PeerIPVariable STRING:RemoteAddr
		PeerHostNameVariable STRING:RemoteHost
		LocalAddressVariable STRING:LocalAddr
		ServerPortVariable RFC822:ServerPort
		Flags OwnDB|DNSReverseLookup|SetPeerAddress|SetLocalAddress
	</Object>

/*___+++CNF_END+++___*/

	<Object>
		Name TCPIPIOObject
		Class TCPIPIOClass
		BindHost localhost			# host to bind to
		BindPort 1200				# port to bind on 
		Type Passive				# Passive (server) or Active (client)
		AcceptTimeout 1000			# applies to Passive only
		RecvTimeout 30
		SendTimeout 60 
		PeerAddressVariable "STRING:RemoteAddr"
		PeerHostNameVariable "STRING:RemoteHost"
		LocalAddressVariable "STRING:LocalAddr"
		ServerPortVariable "RFC822:ServerPort"
		Flags "OwnDB|SetLocalAddress|SetPeerAddress|DNSReverseLookup"
	</Object>

#endif

⌨️ 快捷键说明

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