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

📄 hxnetapi.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (!m_pData)
    {
	return HXR_OUTOFMEMORY;
    }

#ifdef _UNIX
    m_pData->SetAsyncDNSPref( ReadAsyncDNSPref((IUnknown*)m_pContext) );
#endif

    // XXXAAK -- local addr binding stuff
    theErr = m_pData->init(INADDR_ANY, 0);

    m_pData->nonblocking();
    m_pData->set_callback(m_pCallback);

#ifdef _WINDOWS
#if defined (_WIN32)
    ULONG32 ulPlatformData = (ULONG32)GetModuleHandle(NULL);
#elif defined (_WIN16)
    ULONG32 ulPlatformData = (ULONG32)(int)g_hInstance;
#endif
    m_pData->SetWindowHandle(ulPlatformData);
#endif /* defined (_WINDOWS) */

    m_bResolverPending = TRUE;
#ifndef _WINCE
    m_pData->dns_find_ip_addr(pHostName);
#else
    // Only blocking DNS
    m_pData->dns_find_ip_addr(pHostName, 1);
#endif

    return HXR_OK;
}

void
HXResolver::DNSDone(BOOL bSuccess)
{
    ULONG32 ulAddr = 0;
    BOOL bIsValid = TRUE;
    char*   pDottedIP = 0;

    m_bResolverPending = FALSE;

    AddRef();

    if (bSuccess)
    {
	m_pData->dns_ip_addr_found(&bIsValid, &ulAddr);
	UINT32 ulHostAddr = DwToHost(ulAddr);
	m_pResp->GetHostByNameDone(HXR_OK, ulHostAddr);
    }
    else
    {
	m_pResp->GetHostByNameDone(HXR_DNR, 0);
    }

    Release();
}


HX_RESULT
HXResolver::HXResolverCallback::Func(NotificationType Type,
					       BOOL bSuccess, conn* pConn)
{
    if(m_pContext)
    {
	switch (Type)
	{
	case DNS_NOTIFICATION:
	    m_pContext->DNSDone(bSuccess);
	    break;
	case READ_NOTIFICATION:
	case WRITE_NOTIFICATION:
	case CONNECT_NOTIFICATION:
	default:
	    break;
	}
    }
    return HXR_OK;
}


/* HXTCPSocket */
HXTCPSocket::HXTCPSocket(IUnknown* pContext, HXNetworkServices* pNetworkServices):
     m_lRefCount(0)
    ,m_pTCPResponse(0)
    ,m_pCtrl(0)
    ,m_lForeignAddress(0)
    ,m_nForeignPort(0)
    ,m_bReadPending(FALSE)
    ,m_nRequired(0)
    ,mSendTCP(0)
    ,mReceiveTCP(0)
    ,m_pBuffer(0)
    ,m_pCallback(0)
    ,m_bConnected(FALSE)
    ,m_bWantWritePending(FALSE)
    ,m_bInitComplete(FALSE)
    ,m_bWriteFlushPending(FALSE)
    ,m_pScheduler(0)
    ,m_pSchedulerReadCallback(0)
    ,m_pSchedulerWriteCallback(0)
    ,m_bInRead(FALSE)
    ,m_bInWrite(FALSE)
    ,m_bInDoRead(FALSE)
    ,m_pInterruptState(NULL)
    ,m_pResponseInterruptSafe(NULL)
    ,m_pMutex(NULL)
    ,m_bInDestructor(FALSE)
    ,m_pNonInterruptReadCallback(NULL)
    ,m_pNetworkServices(NULL)
    ,m_pPreferences(NULL)
    ,m_bReuseAddr(FALSE)
    ,m_bReusePort(FALSE)
    ,m_pContext(pContext)
    ,m_bSecureSocket(FALSE)
{
    m_pNetworkServices = pNetworkServices;
    m_pNetworkServices->AddRef();

#ifdef _MACINTOSH
	m_pInterruptSafeMacWriteQueue = new InterruptSafeMacQueue();
	HX_ASSERT(m_pInterruptSafeMacWriteQueue != NULL);
#endif

    if (pContext)
    {
	pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);
	pContext->QueryInterface(IID_IHXInterruptState, (void**) &m_pInterruptState);
	pContext->QueryInterface(IID_IHXPreferences, (void**) &m_pPreferences);
    }

    if (m_pScheduler)
    {
	m_pSchedulerReadCallback = new ScheduledSocketCallback(this, TRUE);
	m_pSchedulerReadCallback->AddRef();

	m_pSchedulerWriteCallback = new ScheduledSocketCallback(this, TRUE);
	m_pSchedulerWriteCallback->AddRef();

	m_pNonInterruptReadCallback = new ScheduledSocketCallback(this, FALSE);
	m_pNonInterruptReadCallback->AddRef();

#ifdef _MACINTOSH
	m_pMacCommandCallback = new ScheduledSocketCallback(this, FALSE);
	m_pMacCommandCallback->AddRef();
#endif
    }

#if defined(_UNIX) && defined(HELIX_FEATURE_IGNORE_SIGPIPE)
        // When the connection is closed by the server, SIGPIPE will be thrown
        // in next write() and terminates the program abruptly.
        //
        // In order to gracefully exists the program, it's recommended to:
        // - ignore the SIGPIPE and
        // - checks the return code(errno) from write()
        //
        // for read(), it simply returns 0 when the connection is closed.
        SIGNAL(SIGPIPE, SIG_IGN);
#endif /* _UNIX  && HELIX_FEATURE_IGNORE_SIGPIPE */

#if defined(THREADS_SUPPORTED)
    HXMutex::MakeMutex(m_pMutex);
#elif defined(_UNIX_THREADED_NETWORK_IO)
    if( ReadNetworkThreadingPref((IUnknown*)m_pContext) )
        HXMutex::MakeMutex(m_pMutex);
    else
        HXMutex::MakeStubMutex(m_pMutex);
#else
    HXMutex::MakeStubMutex(m_pMutex);
#endif
}

HXTCPSocket::~HXTCPSocket()
{
    m_bInDestructor = TRUE; // set it early
    m_pMutex->Lock();

#ifdef _MACINTOSH
	HX_DELETE(m_pInterruptSafeMacWriteQueue); // will release any objects in its nodes
#endif

   if (m_pSchedulerReadCallback)
		m_pSchedulerReadCallback->Unschedule(m_pScheduler);

   if (m_pSchedulerWriteCallback)
		m_pSchedulerWriteCallback->Unschedule(m_pScheduler);

   if (m_pNonInterruptReadCallback)
		m_pNonInterruptReadCallback->Unschedule(m_pScheduler);

#ifdef _MACINTOSH
	if (m_pMacCommandCallback)
		m_pMacCommandCallback->Unschedule(m_pScheduler);
#endif

    /*
     * XXX...While handling the m_pCtrl->done it's possible for the
     *       DispatchMessage call in CancelSelect to cause an
     *       asynchronous DoRead to occur. The resulting AddRef/Release
     *       would cause this object to be deleted again, so to prevent
     *       this we set the m_pCallback->m_pContext = 0
     */

   if (m_pCallback)
    {
	m_pCallback->m_pContext = 0;
    }

//#ifndef _UNIX
    /* XXXJR I feel certain this is related to the above comment somehow.
     *       Deleting the ctrl here wreaks havoc on the encoder.
     *       This is a bad solution, but I don't really know
     *       what the right one is.  This at least prevents random crashes
     *       in the encoder.
     *
     * XXXGH commented out the #ifndef because it was breaking my
     *       connectionless control stuff
     *
     */
    if (m_pCtrl)
    {
	m_pCtrl->done();
	m_pCtrl->Release(); // A deleted (0xdddddddd) pointer was used here.
	m_pCtrl = 0;
    }
//#endif

    HX_RELEASE(m_pTCPResponse);
    HX_DELETE(m_pCallback);
    HX_DELETE(mSendTCP);
    HX_DELETE(mReceiveTCP);
    HX_VECTOR_DELETE(m_pBuffer);

    while (m_PendingWriteBuffers.GetCount() > 0)
    {
	IHXBuffer* pBuffer =
		    (IHXBuffer*) m_PendingWriteBuffers.RemoveHead();
	pBuffer->Release();
    }

    if (m_pSchedulerReadCallback)
    {
    	m_pSchedulerReadCallback->m_pSocket = NULL;
    	m_pSchedulerReadCallback->Release();
    	m_pSchedulerReadCallback = NULL;
    }

    if (m_pSchedulerWriteCallback)
    {
    	m_pSchedulerWriteCallback->m_pSocket = NULL;
    	m_pSchedulerWriteCallback->Release();
    	m_pSchedulerWriteCallback = NULL;
    }

    if (m_pNonInterruptReadCallback)
    {
    	m_pNonInterruptReadCallback->m_pSocket = NULL;
    	m_pNonInterruptReadCallback->Release();
    	m_pNonInterruptReadCallback = NULL;
    }

#ifdef _MACINTOSH
   if (m_pMacCommandCallback)
    {
		m_pMacCommandCallback->m_pSocket = NULL;
		m_pMacCommandCallback->Release();
		m_pMacCommandCallback = NULL;
    }
#endif

    HX_RELEASE(m_pInterruptState);
    HX_RELEASE(m_pResponseInterruptSafe);
    HX_RELEASE(m_pScheduler);

    m_pMutex->Unlock();
    HX_DELETE(m_pMutex);

#if defined( _WIN32 ) || defined( _WINDOWS )
    win_net::ReleaseWinsockUsage(this);
#endif

    HX_RELEASE(m_pNetworkServices);
    HX_RELEASE(m_pPreferences);
}

STDMETHODIMP HXTCPSocket::QueryInterface(REFIID riid, void** ppvObj)
{
    QInterfaceList qiList[] =
        {
            { GET_IIDHANDLE(IID_IHXTCPSocket), (IHXTCPSocket*)this },
            { GET_IIDHANDLE(IID_IHXSetSocketOption), (IHXSetSocketOption*)this },
            { GET_IIDHANDLE(IID_IHXTCPSecureSocket), (IHXTCPSecureSocket*)this },
            { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXTCPSocket*)this },
        };

    return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}

STDMETHODIMP_(ULONG32) HXTCPSocket::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

STDMETHODIMP_(ULONG32) HXTCPSocket::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }
    else if (m_lRefCount < 0)
    {
    	// double delete
    	return 0;
    }

    delete this;
    return 0;
}

STDMETHODIMP HXTCPSocket::Init(IHXTCPResponse* pTCPResponse)
{
    if (!pTCPResponse)
    {
	return HXR_UNEXPECTED;
    }

    m_pTCPResponse = pTCPResponse;
    m_pTCPResponse->AddRef();

    m_pTCPResponse->QueryInterface(IID_IHXInterruptSafe,
				   (void**) &m_pResponseInterruptSafe);

    // allocate TCP send and receive queue
    mSendTCP = new CByteGrowingQueue(QUEUE_START_SIZE,1);
    if (!mSendTCP || !mSendTCP->IsQueueValid())
    {
	return HXR_OUTOFMEMORY;
    }
    mSendTCP->SetMaxSize(TCP_BUF_SIZE);

    mReceiveTCP = new CByteGrowingQueue(QUEUE_START_SIZE,1);
    if (!mReceiveTCP || !mReceiveTCP->IsQueueValid())
    {
	return HXR_OUTOFMEMORY;
    }
    mReceiveTCP->SetMaxSize(TCP_BUF_SIZE);

    m_pBuffer = new char[TCP_BUF_SIZE];
    if (!m_pBuffer)
    {
	return HXR_OUTOFMEMORY;
    }

    return HXR_OK;
}

STDMETHODIMP HXTCPSocket::SetResponse(IHXTCPResponse* pTCPResponse)
{
    m_pMutex->Lock();
    HX_RELEASE(m_pTCPResponse);
    m_pTCPResponse = pTCPResponse;
    m_pTCPResponse->AddRef();

    HX_RELEASE(m_pResponseInterruptSafe);
    m_pTCPResponse->QueryInterface(IID_IHXInterruptSafe,
				   (void**) &m_pResponseInterruptSafe);
    m_pMutex->Unlock();
    return HXR_OK;
}

STDMETHODIMP HXTCPSocket::Bind(UINT32 ulLocalAddr, UINT16 nPort)
{
    UINT32	ulMaxBandwidth = 0;
    BOOL	bEnforceMaxBandwidth = TRUE;
    BOOL        bLoadTest = FALSE;
    IHXBuffer* pBuffer = NULL;

    if (m_bInitComplete)
	return HXR_UNEXPECTED;

    m_nLocalPort = nPort;

#if defined( _WIN32 ) || defined( _WINDOWS )
    //	Have we been able to load and initialize the winsock stuff yet?
    if (!win_net::IsWinsockAvailable(this))
    {
	return HXR_FAIL; // HXR_GENERAL_NONET;
    }
#endif

    m_pNetworkServices->UseDrivers();

    HX_RESULT theErr = conn::init_drivers(NULL);

#ifdef _UNIX
    //This one has to be set before we create a new socket.
    conn::SetNetworkThreadingPref( ReadNetworkThreadingPref((IUnknown*)m_pContext) );
    conn::SetThreadedDNSPref( ReadThreadedDNSPref((IUnknown*)m_pContext) );
#endif


    m_pCtrl = NULL;

#if defined(HELIX_FEATURE_SECURECONN)
    if (m_bSecureSocket)
    {
	IHXSSL* pHXSSL = NULL;
	IHXCommonClassFactory* pCCF = NULL;

	if (m_pContext)
	{
	    m_pContext->AddRef();

	    // get the CCF
	    m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&pCCF);

	    HX_RELEASE(m_pContext);
	}

	if (pCCF)
	{
	    pCCF->CreateInstance(IID_IHXSSL, (void**) &pHXSSL);
	    HX_RELEASE(pCCF);
	}

	if (pHXSSL)
	{
	    m_pCtrl = new secureconn(pHXSSL);
	    pHXSSL->Release();
	}
    }
    else
#endif /* HELIX_FEATURE_SECURECONN */
    {
	m_pCtrl  = conn::new_socket(HX_TCP_SOCKET);
    }


    if (!m_pCtrl)
    {
	return HXR_OUTOFMEMORY;
    }

    // XXXGo - As it is implemented, this is the only way...
    if (m_bReuseAddr)
    {
	if (m_pCtrl->reuse_addr(m_bReuseAddr) != HXR_OK)
	{
	    // err...what do we need to do?
	    HX_ASSERT(!"reuse_addr() failed");
	}
    }
    if (m_bReusePort)
    {
	if (m_pCtrl->reuse_port(m_bReusePort) != HXR_OK)
	{
	    // err...what do we need to do?
	    HX_ASSERT(!"reuse_port() failed");
	}
    }

#ifdef _UNIX
    m_pCtrl->SetAsyncDNSPref( ReadAsyncDNSPref((IUnknown*)m_pContext) );
#endif

    m_pCtrl->nonblocking();

    m_pCallback = new TCPSocketCallback;
    if (!m_pCallback)
    {
	return HXR_OUTOFMEMORY;
    }
    m_pCallback->m_pContext = this;
    m_pCtrl->set_callback(m_pCallback);
    m_bInitComplete = TRUE;

    if (m_pPreferences)
    {
	/* Get MaxBandwidth from Prefs */
	ReadPrefINT32(m_pPreferences, "MaxBandwidth", ulMaxBandwidth);
	ReadPrefBOOL(m_pPreferences, "LoadTest", bLoadTest);
	ReadPrefBOOL(m_pPreferences, "EnforceMaxBandwidth", bEnforceMaxBandwidth);

	//If we are in load test mode, never enforce the MaxBandwidth.
	bEnforceMaxBandwidth = bEnforceMaxBandwidth&&!bLoadTest;

	if (ulMaxBandwidth && bEnforceMaxBandwidth)
	{
	    conn::m_ulMaxBandwidth = ulMaxBandwidth / 8;
	}
	else if (!bEnforceMaxBandwidth)
	{
	    conn::m_ulMaxBandwidth = MAX_UINT32;
	}
    }

    return HXR_OK;
}

STDMETHODIMP HXTCPSocket::Connect(const char*	pDestination,
				   UINT16	nPort)
{
    if (!m_bInitComplete)
    {
	HX_RESULT ret = Bind(HXR_INADDR_ANY, 0);
	if (HXR_OK != ret)
		return ret;
    }

    HX_RESULT	theErr		= HXR_OK;
    UINT32	ulPlatformData	= 0;

#if defined (_WIN32)
    ulPlatformData = (UINT32)GetModuleHandle(NULL);
#elif defined (_WIN16)
    ulPlatformData = (UINT32)(int)g_hInstance;
#endif

    m_nForeignPort = nPort;

#ifndef _WINCE
    theErr = m_pCtrl->connect(pDestination,nPort,0,ulPlatformData);
#else
    theErr = m_pCtrl->connect(pDestination,nPort,1,ulPlatformData);
#endif

    theErr = ConvertNetworkError(theErr);
    return theErr;
}

⌨️ 快捷键说明

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