win_net.cpp

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

CPP
2,166
字号
	 ndxConn != pSockMap->End(); ++ndxConn)
    {
	ThreadedConn* pConn = (ThreadedConn*) (*ndxConn);
	if (pProcessConn &&
	    pConn != pProcessConn)
	    continue; // dont process other connections while closing
	if (!pConn->GetActualConn())
	    continue;
	int s = pConn->get_sock();
	if (s != INVALID_SOCKET)
	{
	    if (FD_ISSET(s,&readfds))
	       pConn->DoRead(TRUE);
	}
     }
    return theErr;
}

HX_RESULT  
win_net::CheckForConnection()
{
    HX_ASSERT(m_SocketState == CONN_LISTENNING);

    if (m_SocketState != CONN_LISTENNING)
	return HXR_FAIL;

    sockaddr_in addr;
    int len = sizeof(sockaddr_in);
    memset(&addr, 0, len);
    
    SOCKET sock = sockObj->HXaccept(get_sock(), (sockaddr*)&addr, &len);

    if ( sock == INVALID_SOCKET )
    {
	  int code = sockObj->HXWSAGetLastError();
	// igno all errors...  r
 	  return HXR_WOULD_BLOCK;
    }

    win_net* c = (win_net*)conn::actual_new_socket(HX_TCP_SOCKET);
    c->AddRef();
    conn::add_connection_to_list ( c );

    if ( c )
    {
	c->set_sock(sock);
	c->connect_accept((ULONG32)m_hInst, addr);
	if (mCallBack && (m_SocketState == CONN_LISTENNING))
	{
	    mCallBack->Func(ACCEPT_NOTIFICATION, TRUE, (conn*)c);
	}
    }
    HX_RELEASE(c);
    return HXR_OK;
}
#endif //defined(HELIX_FEATURE_NETWORK_USE_SELECT)


//	This function actually starts an async DNS request
//	It does it on either the first read or first write after we
#ifndef WIN32_PLATFORM_PSPC
//	call ConnectAsync();
HX_RESULT win_net::DoStartAsyncConn()
{
    DEBUGOUTSTR( "win_net::DoStartAsyncConn()\r\n" );
    
    if (!m_pAsyncHost)
    {
	return (mLastError = HXR_FAILED);
    }

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

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

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

    return( mLastError = HXR_WOULD_BLOCK );
}

//	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 win_net::ConnectAsync( LPCSTR host, UINT16 port )
{
    DEBUGOUTSTR( "win_net::ConnectAsync()\r\n" );

    bReadyToWrite = 0;

    if (!host)                 
    {
	mLastError = HXR_DNR;
	return mLastError;
    }
	
    if (get_sock() == INVALID_SOCKET)
    {
	mLastError = HXR_NET_SOCKET_INVALID;
	return mLastError;
    }
	
    struct in_addr addr;  
    char* pTemp = strrchr(host, '.');
    if (pTemp && atoi(pTemp + 1))
    {   /* IP address. */
	addr.s_addr = sockObj->HXinet_addr(host);
	
	if ((UINT)addr.s_addr == (UINT)-1) 
	{
	    mLastError = HXR_DNR;
	    return mLastError;
	}
	else
	{
	    LPSTR			pTemp;
	    hostent			*pHost;

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

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

	    pHost = (hostent *)m_AsyncAddress;

	    // this stores info about current addr 
	    CurrentAddr		= *(ULONG32 *)&addr;

	    m_AsyncPort = port;
	    pTemp = (LPSTR)&addr.s_addr;
	    pHost->h_addr_list = &pTemp;

	    CB_DNSComplete( TRUE );
	}
    } 
    else if (conn::is_cached((char *)host,(ULONG32 *) &addr))
    {
	LPSTR			pTemp;
	hostent			*pHost;

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

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

	pHost = (hostent *)m_AsyncAddress;

	// this stores info about current addr 
	CurrentAddr		= *(ULONG32 *)&addr;

	m_AsyncPort = port;
	pTemp = (LPSTR)&addr.s_addr;
	pHost->h_addr_list = &pTemp;

	CB_DNSComplete( TRUE );
    }
    else
    {
	//	Save the parameters, and tell ourselves we're starting up
	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 win_net::ContinueAsyncConnect()
{
    hostent			*pHost;
    struct in_addr	addr;

    DEBUGOUTSTR( "win_net::ContinueAsyncConnect()\r\n" );

    pHost = (hostent *)m_AsyncAddress;

    if (!pHost)
	return;

    memcpy( &(addr.s_addr), pHost->h_addr, sizeof( addr.s_addr ) ); /* Flawfinder: ignore */
    m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst ,TRUE);
    m_AsyncNotifier->DoAsyncSelect( this );
    
    struct sockaddr_in	SockAddr;

    memset( &SockAddr, 0, sizeof( SockAddr ) );
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = *(long*)&(addr.s_addr);
    SockAddr.sin_port = sockObj->HXhtons( m_AsyncPort );
                

    if(callRaConnect && sockObj->HXconnect( get_sock(), (sockaddr*)&SockAddr, sizeof( SockAddr ) ))
    {   
	int code;
	code = sockObj->HXWSAGetLastError(); 
	if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS)
	{  
	    m_SocketState = CONN_CONNECT_INPROG;
	    mConnectionOpen = 1;
	    return;
	}   

	mLastError = HXR_NET_CONNECT;
	m_SocketState = CONN_CONNECT_FAILED;
	return;
    }       

    m_SocketState = CONN_CONNECT_INPROG;
	              
    mConnectionOpen = 1;
    return;
}

//	Called by the notifier to tell us that the DNS request completed
void win_net::CB_DNSComplete( int iSuccess )
{
    DEBUGOUTSTR( "CB_DNSComplete()\r\n" );

    mDNSDone	 = TRUE;

    if (iSuccess && m_pAsyncHost)
    {
	conn::add_to_cache(m_pAsyncHost, get_addr());
    }

    if (m_DNSOnly)
    {
	if (iSuccess)
	{
	    mHostIPValid = TRUE;
	    mHostIPAddr = get_addr();

	}
	else
	{
	    mHostIPValid = FALSE;
	}
    }
    else
    {
	if (iSuccess)
	{
	    m_SocketState = CONN_CONNECT_INPROG;
	    ContinueAsyncConnect();
	}
	else
	{
	    m_SocketState = CONN_DNS_FAILED;
	}
    }

    if (mCallBack)	 
    {
	mCallBack->Func(DNS_NOTIFICATION, iSuccess);
    }
}

//	Called by the notifier to tell us that the Connection completed
void win_net::CB_ConnectionComplete( int iSuccess )
{
    DEBUGOUTSTR( "CB_ConnectionComplete()\r\n" );

    if (iSuccess)
    {
	m_SocketState = CONN_OPEN;
	if (mCallBack)
	{
	    mCallBack->Func(CONNECT_NOTIFICATION);
	}
    }
    else
    {
	m_SocketState = CONN_CONNECT_FAILED;

	if (mCallBack)	 
	{
	    mCallBack->Func(CONNECT_NOTIFICATION, FALSE);
	}
    }
}

//	Called by the notifier when data ready for read/write
void win_net::CB_ReadWriteNotification( int iType )
{
#ifndef _DEMPSEY
	// noisy output
    DEBUGOUTSTR( "CB_ReadWriteNotification()....\r\n" );
#endif // _DEMPSEY
    //	Should do something here....
    if (mCallBack && (m_SocketState == CONN_OPEN))
    {
	if (iType == FD_WRITE)
	{
	    mCallBack->Func(WRITE_NOTIFICATION);
	}
	else if (iType == FD_READ)
	{
	    mCallBack->Func(READ_NOTIFICATION);
	}
	
	//mCallBack->callback_task( HX_UDP_CALLBACK, NULL );
    }
}

void win_net::CB_AcceptNotification()
{
    DEBUGOUTSTR( "CB_AcceptNotification()....\r\n" );
    HX_ASSERT(m_SocketState == CONN_LISTENNING);
    
    win_net* c = (win_net*)conn::actual_new_socket(HX_TCP_SOCKET);
    c->AddRef();
    conn::add_connection_to_list ( c );

    if ( c )
    {
	sockaddr_in addr;
	int len = sizeof(addr);
	SOCKET sock = sockObj->HXaccept(get_sock(), (sockaddr*)&addr, &len);
	if ( sock != INVALID_SOCKET)
	{
	    c->set_sock(sock);
	    c->connect_accept((ULONG32)m_hInst, addr);

	    if (mCallBack && (m_SocketState == CONN_LISTENNING))
	    {
		mCallBack->Func(ACCEPT_NOTIFICATION, TRUE, (conn*)c);
	    }
	}
    }
    HX_RELEASE(c);
}

void win_net::CB_CloseNotification()
{
    DEBUGOUTSTR( "CB_CloseNotification()....\r\n" );
    m_SocketState = CONN_CLOSED;
    if (mCallBack)
    {
	mCallBack->Func(CLOSE_NOTIFICATION);
    }
}
#endif

HX_RESULT win_net::connect( sockaddr_in *addr )
{
    if(callRaConnect && sockObj->HXconnect( get_sock(), (sockaddr*)addr, sizeof( addr ) ))
    {
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }                   
    
    mConnectionOpen = 1;
    return HXR_OK;     
}


HX_RESULT win_net::write(void * buf, UINT16  *len) 
{
    int got;

    DEBUGOUTSTR( "win_net::write()\r\n" );

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

    if (m_SocketState != CONN_OPEN ) //&& m_SocketState != CONN_DNS_INPROG)
    {
	//	We won't be able to write anything here, so clear this
	//	we'll return why we didn't write anything.
	*len = 0;

	switch( m_SocketState )
	{
	case CONN_DNS_INPROG:
	case CONN_CONNECT_INPROG:
	case CONN_CLOSING:
		return( mLastError = HXR_WOULD_BLOCK );

	case CONN_CLOSED:
		return( mLastError = HXR_NET_SOCKET_INVALID );

	case CONN_NO_CONN:
#ifndef WIN32_PLATFORM_PSPC
		return( DoStartAsyncConn() );
#else
        HX_ASSERT(0 && "No Async net");
        return( HXR_NET_READ );
#endif

	case CONN_DNS_FAILED:
		return( mLastError = HXR_DNR );

	case CONN_CONNECT_FAILED:
		return( mLastError = HXR_NET_CONNECT );
	default:
		//	HUH???
		assert( 0 );
		return( mLastError = HXR_NET_READ );
	};
    }
    else
    {
	got = sockObj->HXsend( get_sock(), (char *)buf, *len, 0 );
	if (got == -1)
	{	
	    int code;
	    *len = 0;
	    code = sockObj->HXWSAGetLastError();
	    // Mask the "so what?" errors
	    if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS) 
	    {
		return HXR_WOULD_BLOCK;
	    }
	    else
	    {
		mLastError = HXR_NET_WRITE;
		return mLastError;
	    }
	}

//#if defined(_DEBUG) && defined(_LOGSMIL)
//	if (::HXDebugOptionEnabled("zLogSMIL"))
//{FILE* f1 = ::fopen("e:\\temp\\foo.txt", "a+"); ::fwrite(buf, got, 1, f1);::fclose(f1);}
//#endif
	*len = got;
	return HXR_OK;
    }
}


HX_RESULT win_net::writeto(void * buf, UINT16  *len, ULONG32 addr, UINT16 port) 
{
    //sendto
    int got;

    sockaddr_in resend_addr;
    
    ::memset( &resend_addr, 0, sizeof( resend_addr ) );
    resend_addr.sin_family = AF_INET;
    resend_addr.sin_addr.s_addr = addr;
    resend_addr.sin_port = sockObj->HXhtons(port);

    got = sockObj->HXsendto(get_sock(), (char *) buf, *len, 0, (sockaddr *)&resend_addr, sizeof (resend_addr)); 
    if (got == -1)
    {	
	int code;
	*len = 0;
	code = sockObj->HXWSAGetLastError();
		// Mask the "so what?" errors
	if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS) 
	{
	    return HXR_WOULD_BLOCK;
	}
	else
	{
	    mLastError = HXR_NET_WRITE;
	    return mLastError;
	}
    }

    *len = got;
    return HXR_OK;
}


HX_RESULT win_net::WriteComplete   (char * Buffer, int length)
{
    int sent = 0;
    unsigned short cur_sent=0;

    while(sent < length)
    {
	cur_sent = length - sent;

	HX_RESULT ret = write(Buffer + sent, &cur_sent);
	if(ret != HXR_OK && ret != HXR_WOULD_BLOCK)
	    break;
	sent += cur_sent;
    }

//	m_SocketState = CONN_NO_CONN;

    if(sent < length)
    {
	mLastError = HXR_NET_WRITE;
	return mLastError;
    }

    return HXR_OK;
}

int win_net::ReadyToWrite()
{
    if(get_sock() < 0)
    {
	bReadyToWrite = 0;
	return bReadyToWrite;
    }

    if(bReadyToWrite)
	return 1;
    
    fd_set writefds;
    FD_ZERO(&writefds);
    FD_SET((UINT32)get_sock(), &writefds);
    
    TIMEVAL timeout;
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    if(sockObj->HXselect(0, NULL, &writefds,NULL, &timeout) == 1)
		bReadyToWrite = 1;
    

⌨️ 快捷键说明

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