win_net.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,166 行 · 第 1/4 页

CPP
2,166
字号

    if (conn::is_cached((char *) host, &mHostIPAddr))
    {
	mHostIPValid = TRUE;
	mDNSDone	= TRUE;
	mLastError = HXR_OK;
	if (mCallBack)	 
	{
	    mCallBack->Func(DNS_NOTIFICATION, TRUE);
	}
	return mLastError;
    }

    char* pTemp = strrchr(host, '.');
    if (pTemp && atoi(pTemp + 1))
    {   /* IP address. */

	struct in_addr addr;  
	mHostIPValid = FALSE;
	mHostIPAddr = 0;
	mDNSDone	= TRUE;

	addr.s_addr = sockObj->HXinet_addr(host);
	
	if ((UINT)addr.s_addr == (UINT)-1) 
	{
	    mLastError = HXR_DNR;
	    return mLastError;
	}

	mHostIPValid = TRUE;
	mHostIPAddr = *(ULONG32 *) &addr;
	conn::add_to_cache((char *) host, mHostIPAddr);

	if (mCallBack)	 
	{
	    mCallBack->Func(DNS_NOTIFICATION, TRUE);
	}
	return HXR_OK;
    } 

    if (blocking)
    {
	struct in_addr addr;  
		            
	mHostIPValid = FALSE;
	mHostIPAddr = 0;
	mDNSDone	= TRUE;

	struct hostent *h = sockObj->HXgethostbyname(host);
	
	if (!h || !h->h_addr ) 
	{
	    mLastError = HXR_DNR;
	    return mLastError;
	}

	memcpy(&addr, h->h_addr, sizeof(struct in_addr)); /* Flawfinder: ignore */

	mHostIPValid = TRUE;
	mHostIPAddr = *(ULONG32 *) &addr;
	conn::add_to_cache((char *) host, mHostIPAddr);

	if (mCallBack)	 
	{
	    mCallBack->Func(DNS_NOTIFICATION, TRUE);
	}
	return( mLastError = HXR_OK);
    }
    else
    {
	if (m_pAsyncHost != host)
	{
	    //	Save the parameters, and tell ourselves we're starting up
	    HX_VECTOR_DELETE(m_pAsyncHost);
	    m_pAsyncHost = ::new_string(host);
	}

	if (!m_AsyncAddress)
	{
	    m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
	}

	if (!m_AsyncAddress)
	{
	    return (mLastError = HXR_OUTOFMEMORY);
	}

	// set the boolean variable that we are only doing async DNs and
	// do not intend to connect
#ifndef WIN32_PLATFORM_PSPC
	m_DNSOnly   = TRUE;

	m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , TRUE);
	m_AsyncNotifier->DoAsyncDNS( this, m_pAsyncHost, m_AsyncAddress, MAXGETHOSTSTRUCT );
	m_SocketState = CONN_DNS_INPROG;
#else 
	m_DNSOnly   = FALSE;
#endif

	return( mLastError = HXR_WOULD_BLOCK );
    }
}


BOOL win_net::dns_ip_addr_found(BOOL * valid, ULONG32 *addr)
{
    if (mDNSDone)
    {
	// reset DNS only flag...
	m_DNSOnly   = FALSE;

	*valid = mHostIPValid;
	*addr  = mHostIPAddr;

	return TRUE;
    }
    else
	return FALSE;
}


BOOL win_net::set_receive_buf_size(int DesiredSize)
{
    int s = get_sock();
    if (s == INVALID_SOCKET) 
    {
	mLastError = HXR_NET_SOCKET_INVALID;
	return FALSE;
    }

    int RcvBufSize = 0;
    int iSize = sizeof(RcvBufSize);
    if (sockObj->HXgetsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&RcvBufSize, 
			      &iSize))
    {
	RcvBufSize = 0;
    }

    if (RcvBufSize < DesiredSize)
    {
	RcvBufSize = DesiredSize;
	if(sockObj->HXsetsockopt(s, SOL_SOCKET, SO_RCVBUF, 
				(char *)&RcvBufSize, sizeof(RcvBufSize)))
	{
	    int code;
	    code = sockObj->HXWSAGetLastError(); 
	    return FALSE;
	}
    }

    return TRUE;
}

/*
*   reuse_addr/reuse_port has to be called before a sock binds.  however, 
*   socket is not available until it binds as it is implemented.  So, set a 
*   flag here and do the actual setsockopt right before a sock binds.
*   Look in init_win().
*/
HX_RESULT	
win_net::reuse_addr(BOOL enable)
{
    m_bReuseAddr = enable;
    return HXR_OK;
}

HX_RESULT	
win_net::reuse_port(BOOL enable)
{
    m_bReusePort = enable;
    return HXR_OK;
}

HX_RESULT
win_net::get_host_name(char* name, int namelen)
{
    HX_ASSERT(sockObj);
    
    if (sockObj->HXgethostname(name, namelen) != 0)
    {
	return HXR_FAILED;
    }
    else
    {
	return HXR_OK;
    }   
}

HX_RESULT
win_net::get_host_by_name(char* name, REF(struct hostent*) h)
{
    HX_ASSERT(sockObj);
    
    h = sockObj->HXgethostbyname(name);
    if (!h || !h->h_addr_list)
    {
	return HXR_DNR;
    }
    else
    {
	return HXR_OK;
    }
}

HX_RESULT win_UDP::set_broadcast(BOOL enable)
{
	int ret;
	SOCKET s = get_sock();
	if(s == INVALID_SOCKET)
	{
		return( mLastError = HXR_NET_SOCKET_INVALID );
	}
	ret = sockObj->HXsetsockopt( s, SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof(UINT32) );
	if(ret == -1)
		ret = HXR_BIND;
	return ret;
}

HX_RESULT 
win_UDP::set_send_size(UINT32 send_size)
{
    int s = get_sock();
    int ret = 0;
again:
    ret = sockObj->HXsetsockopt(s, SOL_SOCKET, SO_SNDBUF,
		     (char*)&send_size, sizeof(INT32));
    if (ret < 0 && send_size > 8192)
    {
	send_size >>= 1;
        goto again;
    }
    return ret;
}


HX_RESULT win_UDP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform ) 
{
    HX_RESULT ret;
    if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
    {                
	if(ret == HXR_BLOCK_CANCELED)
	    return ret;
  
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }

    return win_net::connect(host, port, blocking, ulPlatform );
}

HX_RESULT win_UDP::SetWindowHandle(ULONG32 handle)
{
    m_hInst = (HINSTANCE)handle;
#ifndef WIN32_PLATFORM_PSPC
    m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst ,TRUE);
    m_AsyncNotifier->DoAsyncSelect( this );
#endif
    return HXR_OK;		
}

HX_RESULT win_UDP::connect(sockaddr_in * addr, UINT16 blocking) 
{                
    HX_RESULT ret;
    if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
    { 
	if(ret == HXR_BLOCK_CANCELED)
	    return ret;                                          
	  
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }

    return win_net::connect(addr);
}                                  

HX_RESULT win_TCP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform ) 
{   
    HX_RESULT ret;
    if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
    {    
	if(ret == HXR_BLOCK_CANCELED)
	    return ret;                                          
      
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }

    return win_net::connect(host, port, blocking, ulPlatform );
}

HX_RESULT win_TCP::connect(sockaddr_in * addr, UINT16 blocking) 
{
    HX_RESULT ret;
    if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
    { 
	if(ret == HXR_BLOCK_CANCELED)
	    return ret;                                          
	  
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }

    return win_net::connect(addr);
}

inline HX_RESULT win_UDP::listen(ULONG32 ulLocalAddr, UINT16 port, 
				 UINT16 backlog, UINT16 blocking,
				 ULONG32 ulPlatform)
{
    return HXR_INVALID_OPERATION;
}

inline HX_RESULT win_TCP::listen(ULONG32 ulLocalAddr, UINT16 port, 
				 UINT16 backlog, UINT16 blocking,
				 ULONG32 ulPlatform)
{
    HX_RESULT ret = HXR_NET_SOCKET_INVALID;
    if ( get_sock() < 0 )
    {
	if ( ulLocalAddr == HX_INADDR_ANY )
	    ret = init(INADDR_ANY, port, blocking);
	else
	    ret = init(ulLocalAddr, port, blocking);
    }
    if ( FAILED(ret) )
    {
	if(ret == HXR_BLOCK_CANCELED)
	    return ret;
	mLastError = HXR_NET_SOCKET_INVALID;
	return mLastError;
    }

    return win_net::listen(ulLocalAddr, port, backlog, blocking, ulPlatform);
}


HX_RESULT
win_UDP::set_multicast()
{
#ifdef NO_MULTICAST
    return HXR_MULTICAST_UDP;
#else
    INT32         	ret;
    sockaddr_in addr;
    int addr_len = sizeof addr;

    if (get_sock() == INVALID_SOCKET) 
    {
        // Not connected
        return( mLastError = HXR_NET_SOCKET_INVALID );
    }

    memset(&addr, 0, HX_SAFESIZE_T(addr_len));
    ret = sockObj->HXgetsockname(get_sock(), (sockaddr*)&addr, &addr_len);

    if (ret < 0)
    {
        return HXR_MULTICAST_UDP;
    }

    ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_IF,
                       (char*) &addr.sin_addr.s_addr,
                       sizeof (addr.sin_addr.s_addr));
    if (ret < 0)
    {
	return HXR_MULTICAST_UDP;
    }
    return HXR_OK;

#endif /* NO_MULTICAST */
}

HX_RESULT
win_UDP::set_multicast_ttl(unsigned char ttl)
{
#ifdef NO_MULTICAST
    return HXR_MULTICAST_UDP;
#else
    if (get_sock() == INVALID_SOCKET) 
    {
        // Not connected
        return( mLastError = HXR_NET_SOCKET_INVALID );
    }
    
    INT32         ret;
    INT32         ttl_proxy = ttl;

    ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_TTL,
                       (char*) &ttl_proxy, sizeof (ttl_proxy));

    if (ret < 0)
    {
        return HXR_MULTICAST_UDP;
    }
    return HXR_OK;

#endif /* ! NO_MULTICAST */
}

HX_RESULT win_UDP::join_multicast_group(ULONG32 addr, ULONG32 if_addr)
{	
    int ret;
    ip_mreq		multicast_group;

    if (get_sock() == INVALID_SOCKET) 
    {
	// Not connected
	return( mLastError = HXR_NET_SOCKET_INVALID );
    }
    
    multicast_group.imr_multiaddr.s_addr = sockObj->HXhtonl(addr);
    multicast_group.imr_interface.s_addr = sockObj->HXhtonl(if_addr);
    
    ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multicast_group , sizeof (multicast_group) );
    if (ret == -1)
    {
	int err;
	err = sockObj->HXWSAGetLastError();
	return HXR_MULTICAST_JOIN;
    }
    return HXR_OK;
}

HX_RESULT win_UDP::leave_multicast_group(ULONG32 addr, ULONG32 if_addr)
{
    int ret;
    ip_mreq		multicast_group;

    if (get_sock() == INVALID_SOCKET) 
    {
	// Not connected
	return( mLastError = HXR_NET_SOCKET_INVALID );
    }

    multicast_group.imr_multiaddr.s_addr = sockObj->HXhtonl(addr);
//	multicast_group.imr_multiaddr.s_addr = sockObj->HXinet_addr("226.0.0.8");
    multicast_group.imr_interface.s_addr = sockObj->HXhtonl(if_addr);
    
    ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&multicast_group , sizeof (multicast_group) );
    if (ret == -1)
    {
	return HXR_GENERAL_MULTICAST;
    }

    return HXR_OK;
}
HX_RESULT 
win_UDP::set_multicast_if(ULONG32 ulInterface)
{
    int ret;
    int s = get_sock();
    if(s == INVALID_SOCKET)
    {
	return( mLastError = HXR_NET_SOCKET_INVALID );
    }

    unsigned long addr = sockObj->HXhtonl(ulInterface);    
    ret = sockObj->HXsetsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, 
	(char*)&addr, sizeof(addr));

    if(ret == -1)
	ret = HXR_GENERAL_MULTICAST;
    return ret;
}

HX_RESULT	
win_UDP::GetFromInfo(ULONG32& ulAddr, UINT16& nPort)
{
    return HXR_OK;
}

WinsockManager::WinsockManager()
{
    bInitialized = FALSE;
    Initialize();
}


WinsockManager::~WinsockManager()
{
    conn::close_drivers(NULL);

    bInitialized = FALSE;
}

void
WinsockManager::Initialize()
{
    bInitialized = FALSE;

    HX_ASSERT(!sockObj);
    if(!sockObj)
	sockObj = new CHXSock;  

    if(conn::init_drivers(NULL) != HXR_OK)
	    return;

    if(sockObj && sockObj->WinSockAvail() && sockObj->InitWinsock())
    {
	bInitialized = TRUE;
    }

    UINT8 nWinSockVersion = sockObj->HXGetVersion();

    /*
     * Check to see what platform we are on
     */
    OSVERSIONINFO winver;
    winver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

#ifndef WIN32_PLATFORM_PSPC
    if(GetVersionEx(&winver))
    {
	if(nWinSockVersion == 2	&&
	   winver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
	   winver.dwMinorVersion == 0)
	{
	    /*
	     * Async lookup in Win 95 with WinSock2.0 installed returns the same handle for
	     * multiple requests. If there are multiple outstanding requests, there is
	     * no way to map the handle in the response to the outstansing request since
	     * all replies get mapped to one request. NT 4.0 returns different handles so
	     * name resolution works fine.
	     *
	     * We workaround this by queueing up the DNS requests.
	     */
	    sockGlobals.m_bWinSock2Suck = TRUE;
	}
    }
#endif
}

BOOL    
WinsockManager::IsInitialized()
{
    return bInitialized && sockObj;
}

⌨️ 快捷键说明

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