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

📄 udpipsck.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	/* ---
	**
	**
	** 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 jsut 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:		 UDPIPSocket_onClassLoad
 Synopsis:
 Description:
	This is called on program startup, restart or shutdown.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_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:		 UDPIPSocket_UDPIPSocket
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_UDPIPSocket(
	PIObject *pObject,
	int iArgc,
	const char *ppArgv[]
	)
{
	/*
	** Allocate instance data
	*/
	UDPIPSocketData *pData = new UDPIPSocketData( pObject, iArgc, ppArgv );	
	PIObject_setUserData( pObject, pData );

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

	return PIAPI_COMPLETED;
}

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

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

	/*
	** Allocate instance data
	*/
	pData = new UDPIPSocketData( 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:		UDPIPSocket_xUDPIPSocket
 Synopsis:
 Description:
	Destructor for instances of the UDPIPSocket class. Performs cleanup.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_xUDPIPSocket( PIObject *pObject, int,
	const char *[] )
{
	delete (UDPIPSocketData *)PIObject_getUserData( pObject );
	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:	   UDPIPSocket_send
 Synopsis:
 Description:
	Send data down pObject socket.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_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;
	UDPIPSocketData *pInstanceData=
	(UDPIPSocketData *)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=::sendto(
            pInstanceData->iSocket,
            &(pToSend[iSent]),
            iToSend,
            0,
            (struct sockaddr *)&(pInstanceData->tAddr),
            pInstanceData->iSize ); 
		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:	   UDPIPSocket_recv
 Synopsis:
 Description:
	Get data out of pObject socket.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int UDPIPSocket_recv( PIObject *pObject, void *pData,
	int iLen, int *piReceived, int, const char *[] )
{
	/* --- automatic variables --- */
	int iRet = -1;
	UDPIPSocketData *pInstanceData=
		(UDPIPSocketData *)PIObject_getUserData( pObject );
	assert( pInstanceData && piReceived );

    /*
    ** Check for received data in buffer
    */
    if ( pInstanceData->iReceivedLen > 0 )
        {
        if ( iLen < pInstanceData->iReceivedLen )
            {
            *piReceived = iLen;
            memcpy( pData, pInstanceData->szReceived, iLen );
            pInstanceData->iReceivedLen -= iLen;
            }
        else
            {
            *piReceived = pInstanceData->iReceivedLen;
            memcpy( pData, pInstanceData->szReceived,
                pInstanceData->iReceivedLen );
            pInstanceData->iReceivedLen = 0;
            };

        return PIAPI_COMPLETED;
        };
    
    /*
    ** Read more data
    */
	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=::recvfrom(
            pInstanceData->iSocket,
            (char *)pData,
            iLen,
            0,
            (struct sockaddr *)&(pInstanceData->tAddr),
            &((uint)pInstanceData->iSize) );

		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 UDPIPIOClass
		Type IO
		Library IO
		OnClassLoad UDPIPSocket_onClassLoad
		Constructor UDPIPSocket_UDPIPSocket
		CopyConstructor UDPIPSocket_copyUDPIPSocket
		Destructor UDPIPSocket_xUDPIPSocket
		Out UDPIPSocket_send
		In UDPIPSocket_recv
	</Class>

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

	<Object>
		Name UDPIPIOObject
		Class UDPIPIOClass
		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 + -