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

📄 unix_net.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#ifdef _UNIX_THREADS_SUPPORTEDvoid *unix_net::_ResolveIt( void* pArg ){    unix_net* pIt = (unix_net*)pArg;    struct hostent *h = gethostbyname(pIt->m_pAsyncHost);    if( (NULL!=h) && (NULL!=h->h_addr) )     {        //Got good IP, send it back in dot format.        const u_char *src = (u_char*)h->h_addr_list[0];        static const char fmt[] = "%u.%u.%u.%u";        sprintf(pIt->m_szPipeIP, fmt, src[0], src[1], src[2], src[3]); /* Flawfinder: ignore */    }    pIt->m_nResolved = 1;    return NULL;}#endifHX_RESULT unix_net::DoStartAsyncConn(){    DPRINTF(D_MSG,("unix_net::DoStartAsyncConn()\r\n"));    m_SocketState = CONN_DNS_INPROG;    #ifdef _UNIX_THREADS_SUPPORTED    //Make the thread if we haven't already.    if( m_bThreadedDNS )    {        if( NULL == m_pResolver)        {            m_nResolved    = 0;            HXThread::MakeThread( m_pResolver );            HX_ASSERT( m_pResolver );        }                //Set the state        m_nResolved = 0;        //Start the thread        m_pResolver->CreateThread( _ResolveIt, (void*)this );        //That is it!        return( mLastError = HXR_WOULD_BLOCK );    }#endif    //    // Fork here to start the DNS process. The process will    // be monitored by calls from proccess_idle to the method    // 'CheckOnDNS()'.    //    //Create pipe to communicate between the child and parent.    if ( 0 != pipe(m_anDNSPipe) )    {	//Can't create pipe.	m_anDNSPipe[0] = nInvalidPipe;	m_anDNSPipe[1] = nInvalidPipe;	mLastError = HXR_GENERAL_NONET;	return mLastError;    }    if( 0 > (m_nChildProcID = fork()))    {	//Error trying to fork.	//What should we do?	mLastError = HXR_GENERAL_NONET;	m_SocketState = CONN_DNS_FAILED;	CB_DNSComplete( 0 );	return HXR_GENERAL_NONET;    }        if( 0 == m_nChildProcID )    {	//This is the child proc....	//Close the read end of the pipe.	if ( 0 != ::close( m_anDNSPipe[0]) )	{	    //close, error. Kill this child proc.	    //This proc just exits. Return codes will come	    //from the parent proc. Just write a NULL to 	    //the pipe.	    ::write( m_anDNSPipe[1], "\0", 1 );	    exit(1);	}	m_anDNSPipe[0] = nInvalidPipe;	//	// Do the blocking DNS here	//	struct hostent *h = gethostbyname(m_pAsyncHost);	if ( (NULL==h) || (NULL==h->h_addr) ) 	{	    //Bad host or other nasty.        //printf("Bad host or some other nasty\n");		    //Send back \0 for now.	    ::write( m_anDNSPipe[1], "\0", 1 );	    exit(1);	}	//Got good IP, send it back in dot format.	const u_char *src = (u_char*)h->h_addr_list[0];	char szTmp[20]; /* Flawfinder: ignore */ //Just big enough to hold "255.255.255.255"	static const char fmt[] = "%u.%u.%u.%u";	SafeSprintf(szTmp, 20, fmt, src[0], src[1], src[2], src[3]);        //printf("The Address is: %s\n", szTmp);	        ::write( m_anDNSPipe[1], szTmp, strlen(szTmp)+1 );        //Now close the pipe to ensure an EOF is written.        //Close the read end of the pipe.	if ( 0 != ::close( m_anDNSPipe[1]) )	{            //Unlikly, but if it does happend then we won't get            //an EOF written to the pipe and the AsyncDNS will            //never complete.#ifdef _DEBUG                        fprintf( stderr, "AsyncDNS can't close pipe. Disable AsyncDNS with NoAsyncDNS=1\n");            fprintf( stderr, "If you have problems connecting.\n");#endif            	}	_exit(0);    }//m_nChildProcID    //In parent....    //Close the write end of the pipe.    if ( 0 != ::close(m_anDNSPipe[1]) )    {	//close error.	m_anDNSPipe[0] = nInvalidPipe;	m_anDNSPipe[1] = nInvalidPipe;		mLastError = HXR_GENERAL_NONET;	return mLastError;    }    m_anDNSPipe[1] = nInvalidPipe;        //We are now ready to read off of anDNSPipe[0] the    //IP address of the host in dot format.    //Set the pipes to non blocking.    int flags;    if( (flags = fcntl( m_anDNSPipe[0], F_GETFL, 0)) < 0 )    {	//Error, can't get the current flags for this pipe.	mLastError = HXR_GENERAL_NONET;	m_SocketState = CONN_DNS_FAILED;	//Close the pipes and kill the child proc.	CleanUpChildProc();	//Report the disaster.	CB_DNSComplete(0);	return HXR_GENERAL_NONET;    }    flags |= O_NONBLOCK;    if( fcntl( m_anDNSPipe[0], F_SETFL, flags) < 0 )    {	//Error, can't set the flags for this pipe.	mLastError = HXR_GENERAL_NONET;	m_SocketState = CONN_DNS_FAILED;		//Close the pipes and kill the child proc.	CleanUpChildProc();	//Report the disaster.	CB_DNSComplete(0);	return HXR_GENERAL_NONET;    }    return( mLastError = HXR_WOULD_BLOCK );}HX_RESULT unix_net::CheckOnDNS(){    //Return this if nothing changes.    mLastError = HXR_WOULD_BLOCK;#ifdef _UNIX_THREADS_SUPPORTED    if( m_bThreadedDNS )    {	AddRef();        //Is the thread done yet?        if( m_nResolved == 1 )        {            //Yeah, we are done. Wait on the thread.            m_pResolver->Exit(0);            //use it.            if( strlen(m_szPipeIP) == 0 )            {                //badhost or DNS error. Close the pipe and go home.                mLastError = HXR_DNR;                CB_DNSComplete(0);            }            else            {                //Assume at this point that m_szPipeIP has a good IP in it.                m_sSockAddrIn.sin_addr.s_addr = inet_addr(m_szPipeIP);                if((ULONG32)m_sSockAddrIn.sin_addr.s_addr == (ULONG32)-1)                 {                    mLastError = HXR_DNR;                    CB_DNSComplete(0);                }                else                {                    //Clear it for next time.                    m_szPipeIP[0]='\0';                                        //Set our current address...                    CurrentAddr = m_sSockAddrIn.sin_addr.s_addr;                                        CB_DNSComplete(1);                    mLastError = HXR_OK;                }            }        }	HX_RESULT res = mLastError;	Release();        return res;    }    #endif    //Keep checking and see if the the DNS lookup is    //done or not.    char      szBuff[256]; /* Flawfinder: ignore */    int       status = 0;    //If its there grab it.    memset(szBuff, 0, 256);    status = ::read(m_anDNSPipe[0], szBuff, 255);        if( status > 0 )    {	strncat( m_szPipeIP, szBuff, status ); /* Flawfinder: ignore */    }    //Did we find EOF?    if( 0 == status )    {	//At this point m_szPipeIP has a good IP address or	//an error (NULL byte)		//close the last pipe.	::close(m_anDNSPipe[0]); //Don't care about an error here.	m_anDNSPipe[0] = nInvalidPipe;		if( strlen(m_szPipeIP) == 0 )	{	    //badhost or DNS error. Close the pipe and go home.	    mLastError = HXR_DNR;	    CB_DNSComplete(0);	}	else	{	    //Assume at this point that m_szPipeIP has a good IP in it.	    m_sSockAddrIn.sin_addr.s_addr = inet_addr(m_szPipeIP);	    if((ULONG32)m_sSockAddrIn.sin_addr.s_addr == (ULONG32)-1) 	    {		mLastError = HXR_DNR;		CB_DNSComplete(0);	    }	    else	    {				//Clear it for next time.		m_szPipeIP[0]='\0';						//grab the zombie child.		::waitpid( m_nChildProcID, NULL,  0 );		m_nChildProcID = 0;				//Set our current address...		CurrentAddr = m_sSockAddrIn.sin_addr.s_addr;				CB_DNSComplete(1);		mLastError = HXR_OK;	    }	}    } else if( status<0 && EAGAIN!=errno )    {	//Just make sure the read returned EAGAIN and not	//some other error on the pipe.		m_szPipeIP[0]='\0';	//Kill the DNS child proc and close the pipe we're going home.	CleanUpChildProc();		//Report the problem.	mLastError = HXR_GENERAL_NONET;	CB_DNSComplete(0);    }    return mLastError;}HX_RESULT unix_net::CheckForConnection(){    sockaddr_in cliaddr;    HX_SOCKLEN_T addrlen = sizeof(sockaddr_in);    //memset(&cliaddr, 0, addrlen);        //Return this if nothing changes.    mLastError = HXR_WOULD_BLOCK;        int newSock = accept(&cliaddr, &addrlen);    if ( newSock == INVALID_SOCKET )    {	// igno all errors...  r 	  return HXR_WOULD_BLOCK;    }    else    {        unix_net* pNewConn = (unix_net*)conn::actual_new_socket(HX_TCP_SOCKET);        pNewConn->AddRef();        conn::add_connection_to_list(pNewConn);	if ( pNewConn )	{	    pNewConn->set_sock(newSock);	    if ( SUCCEEDED(pNewConn->connect_accept(&cliaddr)) )	    {	    	mLastError = HXR_OK;	        CB_NewConnectionReady (TRUE, pNewConn);	    }	    else	    {	        CB_NewConnectionReady(FALSE, NULL);	    }	}	else	{	    mLastError = HXR_OUTOFMEMORY;	}    }    return mLastError;}// This method get's called by connect() in the case of an async request// It doesn't however actually start the connection.  It just registers// that we need to do the connection.  DoStartAsyncConn() will really do it.HX_RESULT unix_net::ConnectAsync( const char* host, UINT16 port ){        //If we have our child(forked) process going on then    //make sure we kill it and start a new one. Also, close    //any open pipes.    CleanUpChildProc();    bReadyToWrite = 0;    if (!host)                     {	mLastError = HXR_DNR;	return mLastError;    }	    if (get_sock() == INVALID_SOCKET)    {	mLastError = HXR_NET_SOCKET_INVALID;	return mLastError;    }	    char* pTemp = (char*)strrchr(host, '.');    if (pTemp && atoi(pTemp + 1))    {   /* IP address. */	m_sSockAddrIn.sin_addr.s_addr = inet_addr(host);		if ((UINT)m_sSockAddrIn.sin_addr.s_addr == (UINT)-1) 	{	    mLastError = HXR_DNR;	    CB_DNSComplete(0);	    return mLastError;	}	else	{	    // this stores info about current addr 	    CurrentAddr = m_sSockAddrIn.sin_addr.s_addr;	    m_AsyncPort = port;	    if (m_pAsyncHost != host)	    {		HX_VECTOR_DELETE(m_pAsyncHost);		m_pAsyncHost = ::new_string(host);	    }	    CB_DNSComplete(1);	}    }     else if (conn::is_cached((char *)host,(ULONG32 *) &m_sSockAddrIn.sin_addr.s_addr))    {	// this stores info about current addr 	CurrentAddr = m_sSockAddrIn.sin_addr.s_addr;	m_AsyncPort = port;	if (m_pAsyncHost != host)	{	    HX_VECTOR_DELETE(m_pAsyncHost);	    m_pAsyncHost = ::new_string(host);	}	CB_DNSComplete(1);    }    else    {	//We are going to do Async DNS.....	m_AsyncPort = port;	if (m_pAsyncHost != host)	{	    HX_VECTOR_DELETE(m_pAsyncHost);	    m_pAsyncHost = ::new_string(host);	}	m_SocketState = CONN_NO_CONN;	return(DoStartAsyncConn());    }    return( HXR_OK );} // Once async DNS has commpleted then we'll call this guy to do the// connection (again asynchronously).void unix_net::ContinueAsyncConnect(){    DPRINTF(D_MSG,("unix_net::ContinueAsyncConnect() socket: %d\r\n", get_sock()));    int nResult=0;    nResult = CONNECT( get_sock(),		       (sockaddr*)&m_sSockAddrIn,		       sizeof(m_sSockAddrIn) );    if( nResult != 0 && errno != EISCONN )    {   	if( errno == EWOULDBLOCK || errno == EINPROGRESS || errno == EALREADY )	{	    m_SocketState = CONN_CONNECT_INPROG;	}	else	{	    mLastError = HXR_NET_CONNECT;	    m_SocketState = CONN_CONNECT_FAILED;	    nonblocking();            DPRINTF(D_MSG,("unix_net::ContinueAsyncConnect() CONN_CONNECT_FAILED nResult: %d errno: %d(%s)\r\n", nResult, errno, strerror(errno)));	    CB_ConnectionComplete(0);	}    }    else    {	mConnectionOpen = 1;	CB_ConnectionComplete(1);    }    return;}// Called by the notifier to tell us that the DNS request completedvoid unix_net::CB_DNSComplete( int iSuccess ){    ULONG32 ulNotUsed;        mDNSDone = TRUE;    //Put it into the cache if its good and not there.    if( iSuccess && 	m_pAsyncHost &&	0 == conn::is_cached(m_pAsyncHost, &ulNotUsed)	)    {	conn::add_to_cache(m_pAsyncHost, m_sSockAddrIn.sin_addr.s_addr);    }    if( TRUE == m_DNSOnly )    {		//This is an DNSOnly object. Don't do the connect.	if (iSuccess)	{	    mHostIPValid = TRUE;	    mHostIPAddr = get_addr();   	}	else	{	    mHostIPValid = FALSE;	}    }    else     {	if(iSuccess)	{	    m_SocketState = CONN_CONNECT_INPROG;	}	else	{	    m_SocketState = CONN_DNS_FAILED;	}    }//TRUE==m_DNSOnly    //    // Handle any DNS notification callbacks.    //    if (mCallBack)    {	mCallBack->Func(DNS_NOTIFICATION, iSuccess);    }    if( FALSE==m_DNSOnly && iSuccess )    {	m_sSockAddrIn.sin_family = AF_INET;	m_sSockAddrIn.sin_port = htons( m_AsyncPort );	ContinueAsyncConnect();    }    return;}void unix_net::CB_NewConnectionReady(int iSuccess, unix_net* pConn){    if ( mCallBack )    {        mCallBack->Func(ACCEPT_NOTIFICATION, iSuccess?TRUE:FALSE, (conn*)pConn);    }}// Called by the notifier to tell us that the Connection completedvoid unix_net::CB_ConnectionComplete( int iSuccess ){    DPRINTF(D_MSG,("CB_ConnectionComplete(%d)\r\n", iSuccess) );    if (iSuccess)    {	m_SocketState = CONN_OPEN;    }    else    {	m_SocketState = CONN_CONNECT_FAILED;    }        if (mCallBack)

⌨️ 快捷键说明

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