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

📄 unix_net.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: unix_net.cpp,v 1.6.2.4 2004/07/09 01:46:41 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */#if defined _LINUX && defined __GLIBC__ && 0#define _JAVA_GREENTHREADS#endif// Java with green threads needs you to use the internal entry points// for these system calls#ifdef _JAVA_GREENTHREADS#define READ ::__read#define CONNECT ::__connect#define RECVFROM ::__recvfrom#else#define READ ::read#define CONNECT ::connect#define RECVFROM ::recvfrom#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <assert.h>#include "hxcom.h"#include "hxbuffer.h"#include "timebuff.h"#include "hxtick.h"#include "netbyte.h"#include "platform/unix/unix_net.h"		//	Our declaration#include "hxheap.h"#include "hxslist.h"#include "hxcom.h"#include "hxengin.h"#include "hxstrutl.h"#include <errno.h>#ifdef _IRIX#include <bstring.h>		// 	used in FD_ZERO#endif// #include "netplay.h"		//	why?#ifdef _AIX#include <sys/select.h>#endif#include <sys/types.h> //for waitpid#include <sys/wait.h>  //for waitpid#include <fcntl.h>#ifdef _UNIX_THREADS_SUPPORTED#include "hxthread.h"#endif  int unix_net::InBlockingMode = 0;// This thing doesn't get initialized if this is linked into a shared libraryCHXSimpleList* unix_net::readers = NULL;// So I've done a silly thing and labelled it so.static BOOL silly_unix_hack_initialized = FALSE;const int HOSTSTRUCTSIZE = sizeof( hostent ); unix_net::unix_net() {	set_sock( INVALID_SOCKET );	mLastError = HXR_OK;	callRaConnect = 1;    	bReadyToWrite = 0;	m_SocketState = CONN_CLOSED;	//Async DNS vars.	CurrentAddr    = 0;	m_DNSOnly      = FALSE;	m_anDNSPipe[0] = nInvalidPipe;	m_anDNSPipe[1] = nInvalidPipe;	m_nChildProcID = 0;	m_szPipeIP[0]  = '\0';		read_pending = FALSE;	m_lRefCount	    = 0;	// Don't allocate this yet. Not all unix_net instances are actually	// used to read, and if one isn't, allocating here wastes memory.	m_pInBuffer = NULL;	m_bReuseAddr = FALSE;	m_bReusePort = FALSE;	m_pAsyncHost = NULL;        #ifdef _UNIX_THREADS_SUPPORTED        m_pResolver  = NULL;#endif        }unix_net::~unix_net() {    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);    }    HX_VECTOR_DELETE(m_pInBuffer);     //If the DNS forked proccess is still running lets    //kill it here.    //Ignore any returned error, what would we do anyway?    CleanUpChildProc();    HX_VECTOR_DELETE(m_pAsyncHost);#ifdef _UNIX_THREADS_SUPPORTED    if( m_bThreadedDNS )    {        if(m_pResolver)            m_pResolver->Exit(0);        m_nResolved    = 0;        HX_DELETE( m_pResolver );    }#endif  }void unix_net::CleanUpChildProc(){    //Close any open pipes as well.    if( m_anDNSPipe[0] >= 0 )    {	::close( m_anDNSPipe[0] );	m_anDNSPipe[0] = nInvalidPipe;    }        if( m_anDNSPipe[1] >= 0 )    {	::close( m_anDNSPipe[1] );	m_anDNSPipe[1] = nInvalidPipe;    }        if( m_nChildProcID != 0 )    {	kill( m_nChildProcID, SIGKILL );	m_nChildProcID = 0;    }}unix_net * unix_net::new_socket(UINT16 type){    unix_net *c = NULL;        if(!silly_unix_hack_initialized)    {	readers = new CHXSimpleList;	silly_unix_hack_initialized = TRUE;     }        switch(type)    {    case HX_TCP_SOCKET:	c = new unix_TCP;	readers->AddTail(c);	break;	    case HX_UDP_SOCKET:	c = new unix_UDP;	readers->AddTail(c);	break;    }        return(c);}// init_drivers() should do any network driver initialization here// params is a pointer to a platform specfic defined struct that // contains an required initialization dataHX_RESULT unix_net::init_drivers(void *params){	return(HXR_OK);}/* 	close_drivers() should close any network drivers used by the program 	NOTE: The program MUST not make any other calls to the network drivers 	until init_drivers() has been called */HX_RESULT unix_net::close_drivers(void *params){	return(HXR_OK);}HX_RESULT unix_net::get_host_name(char *name, int namelen){    if (::gethostname(name, namelen) == 0)    {	return HXR_OK;    }    else    {	return HXR_FAIL;    }}HX_RESULT unix_net::get_host_by_name(char *name, REF(struct hostent*) pHostent){    if (pHostent = ::gethostbyname(name))    {        return HXR_OK;    }    else    {        return HXR_FAIL;    }    }HX_RESULT unix_net::host_to_ip_str( char *host, char *ip, UINT32 ulIPBufLen){    HX_RESULT           theErr = HXR_OK;    ULONG32             dwAddress;    struct sockaddr_in  rInAddress;    struct hostent*     pHostEntry;    //	Let's look for this in the cache first    if (conn::is_cached( host, &dwAddress))    {	//Found it, copy the 32bit address into rInAddress	//w/o calling memcpy()	rInAddress.sin_addr.s_addr  = dwAddress;    }    else    { 	// Do DNS on the host name	if (!(pHostEntry = gethostbyname( host )))	{	    // Error	    theErr = HXR_DNR;	}	// Return w/o attempting any copies if there's an error	if (theErr != HXR_OK)	{	    goto FuncExit;	}			// copy the ip address into rInAddress w/o calling memcpy()                            struct in_addr** ppAddr = (struct in_addr**)(pHostEntry->h_addr_list);        memcpy(&rInAddress.sin_addr, ppAddr[0], sizeof(struct in_addr)); /* Flawfinder: ignore */		// add to the dns cache	conn::add_to_cache(host, (ULONG32) rInAddress.sin_addr.s_addr );     }    // Convert the ULONG32 IP address into a string and copy it into ip    SafeStrCpy( ip, inet_ntoa( rInAddress.sin_addr ) , ulIPBufLen);    // Single exit point FuncExit:    return( theErr );}ULONG32	unix_net::AddRef(){    return InterlockedIncrement(&m_lRefCount);}ULONG32 unix_net::Release(){    if (InterlockedDecrement(&m_lRefCount) > 0)    {        return m_lRefCount;    }    delete this;    return 0;}/**   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_unix().*/HX_RESULT	unix_net::reuse_addr(BOOL enable){    m_bReuseAddr = enable;    return HXR_OK;}HX_RESULT	unix_net::reuse_port(BOOL enable){    m_bReusePort = enable;    return HXR_OK;}HX_RESULT unix_net::init_unix(UINT16 type, UINT32 local_addr, UINT16 port,                               UINT16 blocking){                                            int                s = INVALID_SOCKET;    struct sockaddr_in addr;#ifdef _BEOS    char    mode = 1;#else    int	    mode = 1;#endif        mLastError = HXR_OK;#ifdef _BEOS    s = socket(AF_INET, type, 0);#else    s = socket(PF_INET, type, 0);#endif    if (s < 0)     {	mLastError = HXR_NET_SOCKET_INVALID;	return mLastError;    }        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&m_bReuseAddr, sizeof(m_bReuseAddr)) < 0)     {	mLastError = HXR_NET_SOCKET_INVALID;	goto sock_err;    }#if defined SO_REUSEPORT    if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (const char*)&m_bReusePort, sizeof(m_bReusePort)) < 0)     {	mLastError = HXR_NET_SOCKET_INVALID;	goto sock_err;    }#endif                memset(&addr, 0, sizeof addr);    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl(local_addr);    addr.sin_port = htons(port);        if (::bind(s, (sockaddr*)&addr, sizeof addr) < 0)     {	mLastError = HXR_NET_SOCKET_INVALID;	goto sock_err;    }#ifdef FIONBIO    if (!blocking && ioctl(s, FIONBIO, &mode) < 0) #elif SO_NONBLOCK    if (!blocking && setsockopt(s,SOL_SOCKET,SO_NONBLOCK,&mode,1)<0)#else    if (!blocking && ::fcntl(get_sock(), F_SETFL, ::fcntl(get_sock(), F_GETFL, 0) | O_NONBLOCK) < 0)#endif    {	mLastError = HXR_NET_SOCKET_INVALID;	goto sock_err;    }    DPRINTF(D_MSG,("unix_net::socket opened: %d\n", s));    m_SocketState = CONN_OPEN;    set_sock( s );    return mLastError;    sock_err:    ::close(s);    m_SocketState = CONN_NO_CONN;    return mLastError;}#if 0/* mcast_multiple_if test *//* *  it returns a number of multicast enabled NICs with a default multicast *  interface as the very first entry in the pIFList */UINT32unix_net::detectMcastIF(REF(BYTE**) pIFList) {    struct ifconf ifc;    int i;    ifc.ifc_len = sizeof(buff);    ifc.ifc_buf = buff;	if (ioctl(skfd, SIOCGIFCONF, &ifc) >= 0) {    {        // XXXGo        //printf("%s\n", pc);	printf("%u\n", ul);    }    else    {           printf("coudn't detect if\n");    }    //HX_VECTOR_DELETE(pc); }#endifHX_RESULT unix_net::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform){    DPRINTF(D_MSG,("unix_net::connect(): b: %d\n", blocking));        bReadyToWrite = 0;        //Get a host at all?    if(!host)                     {	mLastError = HXR_DNR;	return mLastError;    }    //Do we have a socket yet?    if(get_sock() < 0)                     {	mLastError = HXR_NET_SOCKET_INVALID;	return mLastError;    }        if( blocking )    {	//Set our state.	m_SocketState = CONN_DNS_INPROG;		//check and see if we were passed a dot format IP address.	memset(&m_sSockAddrIn, 0, sizeof(struct sockaddr_in));    	char* pTemp = (char*)strrchr(host, '.');	if (pTemp && atoi(pTemp + 1))	{	    m_sSockAddrIn.sin_addr.s_addr = inet_addr(host);	    	    if ((ULONG32)m_sSockAddrIn.sin_addr.s_addr == (ULONG32)-1) 	    {		mLastError = HXR_DNR;		return mLastError;	    }	    //Set state to show we have the address ready to go.	    m_SocketState = CONN_CONNECT_INPROG;	} 		//do a blocking gethostbyname() call.	if( m_SocketState == CONN_DNS_INPROG )	{ 	    struct hostent *h = gethostbyname(host);	    if (!h || !h->h_addr ) 	    {		mLastError = HXR_DNR;                DPRINTF(D_MSG,("unix_net::connect() HXR_INVALID_HOST\r\n"));		CB_ConnectionComplete(0);		return HXR_DNR;	    }                        struct in_addr** ppAddr = (struct in_addr**)(h->h_addr_list);            memcpy(&m_sSockAddrIn.sin_addr, ppAddr[0], sizeof(struct in_addr)); /* Flawfinder: ignore */	    if (m_pAsyncHost != host)	    {		HX_VECTOR_DELETE(m_pAsyncHost);		m_pAsyncHost = ::new_string(host);	    }	    m_AsyncPort = port; 	}				m_sSockAddrIn.sin_family = AF_INET;	m_sSockAddrIn.sin_port = htons(port);	// this stores info about current addr 	CurrentAddr = m_sSockAddrIn.sin_addr.s_addr;	if(CONNECT(get_sock(), (sockaddr*)&m_sSockAddrIn, sizeof(struct sockaddr_in)))	{   	    if(!blocking && (errno == EWOULDBLOCK || errno == EINPROGRESS))	    {  		mConnectionOpen = 1;		nonblocking();		CB_ConnectionComplete(1);		return HXR_OK;	    }                        DPRINTF(D_MSG,("unix_net::connect() HXR_NET_CONNECT\r\n"));            mLastError = HXR_NET_CONNECT;	    CB_ConnectionComplete(0);	    return HXR_NET_CONNECT;	}       	 	      	mConnectionOpen = 1;	nonblocking();	m_SocketState = CONN_OPEN; // Rahul	bReadyToWrite = 1;	CB_ConnectionComplete(1);	return HXR_OK;    }//blocking    return ConnectAsync( host, port );}

⌨️ 快捷键说明

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