win_net.cpp

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

CPP
2,166
字号
    return bReadyToWrite;        
}

void win_net::done (void)
{
#ifndef WIN32_PLATFORM_PSPC
    m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , FALSE);
    if (m_AsyncNotifier)
    {
	m_AsyncNotifier->CancelSelect( this );
    }
#endif

    m_SocketState = CONN_CLOSING;
    if ((get_sock() != INVALID_SOCKET) && sockObj)
    {       
	if (sockObj->HXclosesocket(get_sock()))
	{
	    int code = 0;
	    code = sockObj->HXWSAGetLastError();
	}    
    }	

    set_sock( INVALID_SOCKET );
    m_SocketState = CONN_CLOSED;
    mConnectionOpen = 0;
}

inline HX_RESULT win_net::listen(ULONG32 ulLocalAddr, UINT16 port, 
				 UINT16 backlog, UINT16 blocking,
				 ULONG32 ulPlatform)
{
    m_hInst = (HINSTANCE)ulPlatform;

// accept is polled
#ifndef WIN32_PLATFORM_PSPC
    m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier(m_hInst ,TRUE);
    m_AsyncNotifier->DoAsyncSelect((win_net*)this );
#endif

    HX_RESULT ret = sockObj->HXlisten(get_sock(), backlog);
    if ( SUCCEEDED(ret) )
    {
	m_SocketState = CONN_LISTENNING;
	ret = HXR_OK;
    }
    else
    {
	ret = HXR_NET_SOCKET_INVALID;
    }
    return ret;
}

inline HX_RESULT win_net::blocking (void)
{
    unsigned long nonblocking = 0;
    return sockObj->HXioctlsocket(get_sock(), FIONBIO, &nonblocking); 
}
	
inline HX_RESULT win_net::nonblocking (void) 
{
    unsigned long nonblocking = 1;
    return sockObj->HXioctlsocket(get_sock(), FIONBIO, &nonblocking); 
}

HX_RESULT win_net::connect_accept(ULONG32 ulPlatform, sockaddr_in addr)
{
    m_hInst = (HINSTANCE)ulPlatform;
    
    CurrentAddr = addr.sin_addr.s_addr;

    // set up the new connection so it will use its own notifier. 
    // now we want to add this so it will recieve messages.
#ifndef WIN32_PLATFORM_PSPC
    m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst, TRUE);
    m_AsyncNotifier->DoAsyncSelect(this);
#endif

    m_SocketState = CONN_OPEN;
    mConnectionOpen = 1;

    return HXR_OK;
}

CHXMapPtrToPtr win_net::zm_MapObjectsToWinsockTasks;
CHXMapPtrToPtr win_net::zm_WinsockTasksRefCounts;
int win_net::zm_LibRefCount = 0;


BOOL win_net::IsWinsockAvailable(void* pObject)
{
    BOOL bWinSockInitedForTask = FALSE;

    // First check to see that the drivers are loaded...
    //
    // NOTE: this doesn't include initializing Winsock for 
    // the object's task...

    if(!OnlyOneOfThisInTheWholeProgram.IsInitialized())
    {
	OnlyOneOfThisInTheWholeProgram.Initialize();
    }

    if(OnlyOneOfThisInTheWholeProgram.IsInitialized())
    {
	zm_LibRefCount++;
    
    // Make sure Winsock is initialized for the object's task...

	// get current task.
#if defined( WIN32 )
	void* ulTask = (void*)GetCurrentProcessId();
#else
	void* ulTask = (void*)GetCurrentTask();
#endif

	// add map of object (http or session) to task
	zm_MapObjectsToWinsockTasks[pObject] = ulTask;

	// bump up ref count for task
	void* pVoid;
	ULONG32 TaskRefCount = 0;

	if (zm_WinsockTasksRefCounts.Lookup(ulTask,pVoid))
	{
		TaskRefCount = (ULONG32)pVoid;
	}
	TaskRefCount++;

	bWinSockInitedForTask = TRUE;

	HX_ASSERT_VALID_PTR(sockObj);
	zm_WinsockTasksRefCounts[ulTask] = (void*)TaskRefCount;
    }

    return bWinSockInitedForTask;
}

BOOL win_net::ReleaseWinsockUsage(void* pObject)
{
    // Only do any of this if we've first called IsWinsockAvailable()
    if (zm_LibRefCount > 0)
    {
	// get previous task from map of object (http or session) to task
	void* ulTask;

	if (zm_MapObjectsToWinsockTasks.Lookup(pObject,ulTask))
	{
	    zm_MapObjectsToWinsockTasks.RemoveKey(pObject);

	    // bump up ref count for task
	    void* pVoid;
	    ULONG32 TaskRefCount = 0;
	    if (zm_WinsockTasksRefCounts.Lookup(ulTask,pVoid))
	    {
		TaskRefCount = (ULONG32)pVoid;
	    }
	    TaskRefCount--;

	    // if 0 then call WSACleanup
	    if (TaskRefCount == 0)
	    {
		zm_WinsockTasksRefCounts.RemoveKey(ulTask);
	    }
	}

	// Decerement total ref count
	zm_LibRefCount--;
    }

    return TRUE;
}

HX_RESULT win_net::read(void * buf, UINT16 *len) 
{
    int 		got;
    static int breakpoint = 0;

    assert( buf );
    assert( len );

// This DEBUGOUTSTR is noisy.
#ifndef _DEMPSEY
    DEBUGOUTSTR( "win_net::read()\r\n" );
#endif // !_DEMPSEY

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

    //	Is the TCP socket actually connected yet?
    /* We want to read data even if we have received CloseNotification. 
     * This is because some unread data may be still be in the pipe
     * - RA 10/01/1997
     */
    if (m_SocketState != CONN_OPEN && m_SocketState != CONN_CLOSED)
    {
	//	No
	//	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???
		HX_ASSERT (FALSE);
		return( mLastError = HXR_NET_READ );
	};
    }
    else
    {
	//	Now we can actually do the read
	if (callRaConnect)
	{	
	    got = sockObj->HXrecv( get_sock(), (char *)buf, *len, 0 );
	}
	else
	{
	    int 		fromlen;
	    struct sockaddr 	from;
	
	    fromlen = sizeof( from );
	    got = sockObj->HXrecvfrom( get_sock(), (char *)buf, *len, 0, &from, &fromlen );
	    if (got > 0) breakpoint++;
	}

	// Did we get an error?
	if (got == SOCKET_ERROR) 
	{   
	    *len = 0;

	    if (m_SocketState == CONN_CLOSED)
	    {
		return( mLastError = HXR_NET_SOCKET_INVALID );
	    }

	    int code;

	    code = sockObj->HXWSAGetLastError();

	    //	Translate the error
	    switch (code)
	    {
	    case WSAEWOULDBLOCK:
	    case WSAEINPROGRESS:
		    return( mLastError = HXR_WOULD_BLOCK );

	    case WSAEFAULT:
	    case WSAENOTCONN:
	    case WSAENOTSOCK:
		    return( mLastError = HXR_NET_SOCKET_INVALID );

	    case WSAENETDOWN:
		    return( mLastError = HXR_GENERAL_NONET );

	    case WSAEINTR:
		    return( mLastError = HXR_BLOCK_CANCELED );

	    case WSAEMSGSIZE:
		    return( mLastError = HXR_MSG_TOOLARGE);

	    case WSAETIMEDOUT:
	    case WSAESHUTDOWN:
	    case WSAECONNABORTED:
		    return( mLastError = HXR_SERVER_DISCONNECTED );

	    case WSAECONNRESET:
		/*
		 * WinSock Recvfrom() Now Returns WSAECONNRESET Instead of Blocking or Timing Out (Q263823)
		 * workaround
		 */
		if (!m_bIgnoreWSAECONNRESET)
		{
		    return( mLastError = HXR_SERVER_DISCONNECTED );
		}
		else
		{
		    return( mLastError = HXR_WOULD_BLOCK );
		}

	    default:
		    return( mLastError = HXR_NET_READ );   // Error we don't know what to do about
	    }
	    //	Shouldn't really get here
	    return( mLastError );
	}
	else if (got == 0 && *len != 0)
	{
	    *len = 0;	

	    if (m_SocketState == CONN_CLOSED)
	    {
		return( mLastError = HXR_NET_SOCKET_INVALID );
	    }
	    else
	    {
		return( mLastError = HXR_SERVER_DISCONNECTED );
	    }
	}
	else
	{
	    //	This should be our exit point for successful read
	    *len = got;
	    return( HXR_OK );
	}
    }
}

HX_RESULT	
win_net::readfrom (REF(IHXBuffer*) pBuffer,
		   REF(UINT32)	    ulAddress,
		   REF(UINT16)	    ulPort)
{
    int 		got = 0;
    UINT16		size = 0;

#ifndef _DEMPSEY
    DEBUGOUTSTR( "win_net::readfrom()\r\n" );
#endif // !_DEMPSEY

    pBuffer = NULL;
    ulAddress = 0;
    ulPort = 0;

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

    /* We want to read data even if we have received CloseNotification. 
     * This is because some unread data may be still be in the pipe
     * - RA 10/01/1997
     */
    if (m_SocketState != CONN_OPEN && m_SocketState != CONN_CLOSED)
    {
	//	No
	//	We won't be able to write anything here, so clear this
	//	we'll return why we didn't write anything.
	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???
		HX_ASSERT (FALSE);
		return( mLastError = HXR_NET_READ );
	};
    }
    else
    {
	int 			fromlen;
	struct sockaddr_in 	from;
    
	fromlen = sizeof( from );

	got = sockObj->HXrecvfrom( get_sock(), m_pInBuffer, TCP_BUF_SIZE, 0, (struct sockaddr*)&from, &fromlen );

	// Did we get an error?
	if (got == SOCKET_ERROR) 
	{   
	    if (m_SocketState == CONN_CLOSED)
	    {
		return( mLastError = HXR_NET_SOCKET_INVALID );
	    }

	    int code;

	    code = sockObj->HXWSAGetLastError();

	    //	Translate the error
	    switch (code)
	    {
	    case WSAEWOULDBLOCK:
	    case WSAEINPROGRESS:
		    return( mLastError = HXR_WOULD_BLOCK );

	    case WSAEFAULT:
	    case WSAENOTCONN:
	    case WSAENOTSOCK:
		    return( mLastError = HXR_NET_SOCKET_INVALID );

	    case WSAENETDOWN:
		    return( mLastError = HXR_GENERAL_NONET );

	    case WSAEINTR:
		    return( mLastError = HXR_BLOCK_CANCELED );

	    case WSAEMSGSIZE:
		    return( mLastError = HXR_MSG_TOOLARGE);

	    case WSAETIMEDOUT:
	    case WSAESHUTDOWN:
	    case WSAECONNABORTED:
		    return( mLastError = HXR_SERVER_DISCONNECTED );

	    case WSAECONNRESET:
		/*
		 * WinSock Recvfrom() Now Returns WSAECONNRESET Instead of Blocking or Timing Out (Q263823)
		 * workaround
		 */
		if (!m_bIgnoreWSAECONNRESET)
		{
		    return( mLastError = HXR_SERVER_DISCONNECTED );
		}
		else
		{
		    return( mLastError = HXR_WOULD_BLOCK );
		}
		    
	    default:
		    return( mLastError = HXR_NET_READ );   // Error we don't know what to do about
	    }
	    //	Shouldn't really get here
	    return( mLastError );
	}
	else if (got == 0)
	{
	    if (m_SocketState == CONN_CLOSED)
	    {
		return( mLastError = HXR_NET_SOCKET_INVALID );
	    }
	    else
	    {
		return( mLastError = HXR_SERVER_DISCONNECTED );
	    }
	}
	else
	{
	    //	This should be our exit point for successful read
	    CHXTimeStampedBuffer* pTimeBuffer = new CHXTimeStampedBuffer;
	    pTimeBuffer->AddRef();
	    pTimeBuffer->SetTimeStamp(HX_GET_TICKCOUNT());
	    pTimeBuffer->Set((UCHAR*)m_pInBuffer, got);
	    pBuffer = (IHXBuffer*) pTimeBuffer;

	    ulAddress = DwToHost(from.sin_addr.s_addr);
	    ulPort = WToHost(from.sin_port);
	    
	    return( HXR_OK );
	}
    }
}
    
ULONG32 win_net::get_addr()
{
    hostent			*pHost = (hostent *)m_AsyncAddress;
    ULONG32 addr = 0;
    
    // if CurrentAddr is set, we must have passed
    // a dotted IP address...
    if (CurrentAddr)
    {
	addr = CurrentAddr;
    }
    else if (pHost)
    {
	addr = (ULONG32) (*(ULONG32*)pHost->h_addr);
    }

    return addr;
}

UINT16 win_net::get_local_port()
{
    sockaddr_in addr;
    int addr_len = sizeof addr;
    memset(&addr, 0, HX_SAFESIZE_T(addr_len));
    int ret = sockObj->HXgetsockname(get_sock(), (sockaddr*)&addr, &addr_len);
 
    return (ret < 0) ? -1: WToHost(addr.sin_port);
}


// we need it for dns_find_ip_addr since async stuff needs a window handle...
HX_RESULT win_net::SetWindowHandle(ULONG32 handle) 
{
    m_hInst = (HINSTANCE)handle; 
    return HXR_OK;
}



HX_RESULT win_net::dns_find_ip_addr(const char * host, UINT16 blocking)
{
    if(!host)                 
    {
	mLastError = HXR_DNR;
	return mLastError;
    }

    if(get_sock() < 0)                 
    {
	mLastError = HXR_NET_SOCKET_INVALID;
	return mLastError;
    }

⌨️ 快捷键说明

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