unix_net.cpp

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

CPP
2,212
字号
    {
	mCallBack->Func(CONNECT_NOTIFICATION, iSuccess?TRUE:FALSE);
    }
}

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

void unix_net::CB_CloseNotification()
{
    DPRINTF(D_MSG,("CB_CloseNotification()....\r\n") );
    m_SocketState = CONN_CLOSED;
}


HX_RESULT unix_net::connect( sockaddr_in *addr )
{
    //XXXgfw Is this method used?????
    //XXXgfw If this is used, should there be a non-blocking
    //XXXgfw version of this? If so, we need to pass in a flag
    //XXXgfw or something. Eitherway, I can't see where this is
    //XXXgfw used at all. Only blocking for now I guess.
    
    if(CONNECT( get_sock(), (sockaddr*)addr, sizeof( addr ) ))
    {
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }                   
    
    mConnectionOpen = 1;
    return HXR_OK;     
}


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

	DPRINTF(D_MSG, ("unix_net::write() s: %d l: %d\n",get_sock(),*len));

	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:
			return( mLastError = HXR_NET_CONNECT );
			// return( DoStartAsyncConn() );

		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
	{
#if defined(_BEOS)
		got = ::send( get_sock(), (void *)buf, *len, 0 );
#else
		got = ::write( get_sock(), (char *)buf, *len );
#endif
		if (got == -1)
		{	
			*len = 0;
				// Mask the "so what?" errors
			if (errno == EWOULDBLOCK || errno == EINPROGRESS) 
			{
			   return HXR_WOULD_BLOCK;
			}
			else
			{
			   mLastError = HXR_NET_WRITE;
			   return mLastError;
			}
		}
		*len = got;
		
		return HXR_OK;
	}
}

HX_RESULT unix_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 unix_net::ReadyToWrite()
{
	if(get_sock() < 0)
	{
		bReadyToWrite = 0;
		return bReadyToWrite;
	}

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

#ifdef _HPUX
	// mwebb added HP-specifix lines (for the curious, do "man select")
	// also changed timeout call to be a non-blocking "poll"
	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
#endif
	if(select(0, NULL, &writefds,NULL, &timeout) == 1)
	    bReadyToWrite = 1;
	return bReadyToWrite;        
}

void unix_net::done (void)
{
    m_SocketState = CONN_CLOSING;
    if ((get_sock() != INVALID_SOCKET))
    {
        ::close(get_sock());
    }	
    set_sock( INVALID_SOCKET );
    m_SocketState = CONN_CLOSED;
    mConnectionOpen = 0;
    
    LISTPOSITION listpos = readers->Find(this);
    if(listpos)
    {
	readers->RemoveAt(listpos);
    }
}

inline HX_RESULT unix_net::listen (UINT16 	backlog)
{
    if ( ::listen(get_sock(), backlog) != -1 )
    {
        m_SocketState = CONN_LISTENNING;
	mConnectionOpen = 0;
	return HXR_OK;
    }
    else
    {
	m_SocketState = CONN_NO_CONN;	
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }
}

/*
inline HX_RESULT unix_net::blocking (void)
{
    unsigned long nonblocking = 0;
    return ::ioctl(get_sock(), FIONBIO, (char*)&nonblocking); 
}
	
inline HX_RESULT unix_net::nonblocking (void) 
{
    unsigned long nonblocking = 1;
    return ::ioctl(get_sock(), FIONBIO, (char*)&nonblocking); 
}
*/

inline HX_RESULT unix_net::connect_accept(sockaddr_in *addr)
{
    CurrentAddr = addr->sin_addr.s_addr;
    memcpy(&m_sSockAddrIn, addr, sizeof(sockaddr_in)); /* Flawfinder: ignore */
    mConnectionOpen = 1;
    m_SocketState = CONN_OPEN;
    mLastError = HXR_OK;
    nonblocking();
    return HXR_OK;
}
/*										 
inline HX_RESULT unix_net::accept (sockaddr_in *addr, UINT16 *addrlen)
{
    return ::accept(get_sock(), (sockaddr*)addr, (int *)addrlen);
}

inline HX_RESULT unix_net::bind (sockaddr_in *addr)
{
    return ::bind(get_sock(), (sockaddr*)addr, sizeof(addr));
}
*/

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

	assert( (PTR_INT)buf );
	assert( (PTR_INT)len );


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

	//	Is the TCP socket actually connected yet?
	if (m_SocketState != CONN_OPEN)
	{
		//	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:
			return( mLastError = HXR_NET_CONNECT );
			// return( DoStartAsyncConn() );

		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
	{
		//	Now we can actually do the read
#ifdef _BEOS
        got = ::recv( get_sock(), (char *)buf, *len, 0 ); 
#else
		got = READ( get_sock(), (char *)buf, *len );
#endif

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

			//	Translate the error
			switch (errno)
			{
			case EWOULDBLOCK:
			    add_read_request();
			    return( mLastError = HXR_WOULD_BLOCK );

			case ECONNRESET:
				return( mLastError = HXR_SERVER_DISCONNECTED );

			default:
				return( mLastError = HXR_NET_READ );   // Error we don't know what to do about
			}
		}
		else if (got == 0) 
		{
			return (mLastError = HXR_SERVER_DISCONNECTED);
		}
		else
		{
			//	This should be our exit point for successful read
			DPRINTF(D_MSG, ("unix_net::read() s: %d l: %d\n",get_sock(),*len));
			*len = got;
			return( HXR_OK );
		}
	}
}

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

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

    // Allocate m_pInBuffer now, since we know we need it.
    if( m_pInBuffer == NULL )
    {
	m_pInBuffer = new char[TCP_BUF_SIZE];
    }

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

    //	Is the TCP socket actually connected yet?
    if (m_SocketState != CONN_OPEN)
    {
	//	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:
		return( mLastError = HXR_NET_CONNECT );
		// return( DoStartAsyncConn() );

	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
    {
#if defined _AIX42
	//SCO's Unixware compiler will choke and die otherwise:
  	size_t	    fromlen = 0;
#elif defined _HPUX
	int fromlen = 0;
#else
	socklen_t   fromlen = 0;
#endif
	struct	sockaddr_in from;

	fromlen = sizeof(from);

	//	Now we can actually do the read
	got = RECVFROM( get_sock(), m_pInBuffer, TCP_BUF_SIZE, 0, (struct sockaddr*)&from, (HX_SOCKLEN_T *)&fromlen);

	// Did we get an error?
	if (got <= 0 ) 
	{   	
	    //	Translate the error
	    switch (errno)
	    {
	    case EWOULDBLOCK:
		add_read_request();
		return( mLastError = HXR_WOULD_BLOCK );

	    case ECONNRESET:
		    return( mLastError = HXR_SERVER_DISCONNECTED );

	    default:
		    return( mLastError = HXR_NET_READ );   // Error we don't know what to do about
	    }
	}


        //	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 );
    }
}

HX_RESULT unix_UDP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform ) 
{
    blocking = GetAsyncDNSPref() ? 1 : blocking;

    HX_RESULT ret = HXR_OK;
    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;
    }

    ret = unix_net::connect(host, port, blocking, ulPlatform );
    if ( !ret )
	nonblocking();
	
    return ret;
}

HX_RESULT unix_UDP::connect(sockaddr_in * addr, UINT16 blocking) 
{

    blocking = GetAsyncDNSPref() ? 1 : blocking;

    HX_RESULT ret = HXR_OK;
    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 unix_net::connect(addr);
}                                  

HX_RESULT unix_TCP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform ) 
{
    blocking = GetAsyncDNSPref() ? 1 : blocking;

    HX_RESULT ret = HXR_OK;
    
    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;
    }
    ret = unix_net::connect(host, port, blocking, ulPlatform );
#if 0
    if ( !ret )
	nonblocking();
#endif
    return  ret;
}

HX_RESULT unix_TCP::connect(sockaddr_in * addr, UINT16 blocking) 
{
    blocking = GetAsyncDNSPref() ? 1 : blocking;

    HX_RESULT ret = HXR_OK;
    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 unix_net::connect(addr);
}

HX_RESULT unix_TCP::listen(ULONG32 ulLocalAddr, UINT16 port,
			   UINT16 backlog, UINT16 blocking, 
			   ULONG32 ulPlatform) 
{
    // We will ignor the blockng parameter, and block for this
    // function but leave the socket in a non blocking state...
    HX_RESULT ret = HXR_OK;
    if ( get_sock() < 0 )
    {
	if ( ulLocalAddr == HX_INADDR_ANY )
	    ret = init(INADDR_ANY, port, 1);
	else
	    ret = init(ulLocalAddr, port, 1);
    }
    if ( FAILED(ret) )
    {
	if(ret == HXR_BLOCK_CANCELED)
	    return ret;
	mLastError = HXR_NET_CONNECT;
	return mLastError;
    }
    if ( unix_net::listen(backlog) != HXR_OK)
    {
        ret = HXR_NET_CONNECT;
    }

    if ( SUCCEEDED(ret) )
    {
        ret = unix_net::nonblocking();

⌨️ 快捷键说明

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