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

📄 ot_udp.cp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CP
📖 第 1 页 / 共 2 页
字号:
			{
				UInt8 buf1[256];
				UInt8 buf2[256];
				
				UDErr.addr.maxlen = 256;
				UDErr.addr.buf = buf1;
				UDErr.opt.maxlen = 256;
				UDErr.opt.buf = buf2;
				lookErr = ::OTRcvUDErr(mRef, &UDErr);
				theErr = HXR_NET_WRITE;
			}
			else
			{
				theErr =  HXR_NET_WRITE;
				break;
			}
			}
                        break;
			
		default:
			theErr =  HXR_NET_WRITE;
			break;
	}
	
	*size = 0;
	mLastError = theErr;
	
	return theErr;
}




/*******************************************************************************
** read
********************************************************************************/

HX_RESULT
OT_UDP::read (void *data, UINT16 *len)
{
	return HXR_NOTIMPL;
}

HX_RESULT
OT_UDP::readfrom (REF(IHXBuffer*)   pBuffer,
				  REF(UINT32)	    ulAddress,
				  REF(UINT16)	    ulPort)
{
	UINT16		size = 0;
	OSStatus	theErr = HXR_OK;
	TUnitData	unitdata;
	OTFlags		flags;
	InetAddress	sin;

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

	mLastError = HXR_OK;
	
	if(!mDataArrived)
	{
		return HXR_WOULD_BLOCK;
	}
	
	unitdata.opt.len = 0;
	unitdata.addr.len = 0;
	unitdata.udata.len = 0;
	unitdata.addr.maxlen = sizeof(struct InetAddress);
	unitdata.opt.maxlen = 0;
	unitdata.opt.buf = 0;
	unitdata.udata.maxlen = TCP_BUF_SIZE;			// used to be 256
	unitdata.udata.buf = (UInt8*)m_pInBuffer;
	unitdata.addr.buf = (UInt8*) &sin;

	theErr = OTRcvUData(mRef,&unitdata, &flags);

	if (theErr == HXR_OK)
	{
		size = unitdata.udata.len;
		
		/* I have seen the size to be a really large value some times.
		 * This was before I added initializaion of
 	     *  unitdata.opt.len = 0;
	     *  unitdata.addr.len = 0;
	     *  unitdata.udata.len = 0;
	     *
	     * It looks like sometimes OTRecvData returns no error and DOES NOT
	     * set the udata.len value. We now make sure that we have indeed
	     * received some data before creating an IHXBuffer
	     *
	     * XXXRA
	     */
		 
		HX_ASSERT(size > 0);		
		if (size > 0)
		{
		    CHXTimeStampedBuffer* pTimeBuffer = new CHXTimeStampedBuffer;
		    pTimeBuffer->AddRef();
		    pTimeBuffer->SetTimeStamp(HX_GET_TICKCOUNT());
		    pTimeBuffer->Set((UCHAR*)m_pInBuffer, size);
		    pBuffer = (IHXBuffer*) pTimeBuffer;

		    ulAddress = DwToHost(sin.fHost);
		    ulPort = WToHost(sin.fPort);
		}
	}	
	else if(theErr == kOTNoDataErr)
	{
		theErr = HXR_NO_DATA;
		// xxxbobclark This used to return HXR_OK if there was no data.
		// But now there's threaded networking code that needs to rely
		// on this returning HXR_NO_DATA if there's really no data.
	}
	else if(theErr == kEWOULDBLOCKErr)
		theErr = HXR_WOULD_BLOCK;
	else
		theErr = HXR_SERVER_DISCONNECTED;

	mLastError = theErr;
	return theErr;
}
/*
HX_RESULT
OT_UDP::listen (UINT16 	backlog)
{
	return(HXR_INVALID_OPERATION);
}
*/	
HX_RESULT
OT_UDP::connect(

	const char	*host, 
	UINT16 		port,
	UINT16 		blocking,
	ULONG32	ulPlatform)

{
	return(HXR_INVALID_OPERATION);
}
	

/* join_multicast_group() has this socket join a multicast group */
HX_RESULT
OT_UDP::join_multicast_group (ULONG32 multicastHost, ULONG32 if_addr)
{
	OSStatus		theErr = kOTNoError;

	// mLocalPort is set by the init() function
	// ::OTInitInetAddress(&mMulticastAddr, mLocalPort, multicastHost);

	// since we are already bound to an IP addr on our system
	// (bind occurred in the init() function) we can now Let 
	// IP know to listen for this multicast IP address on all interfaces.
	
	TOptMgmt 			optReq;
	UInt8	 			optBuffer[ kOTOptionHeaderSize + sizeof(TIPAddMulticast) ];
	ULONG32				optLength = kOTOptionHeaderSize + sizeof(TIPAddMulticast);
	TOption*	 		opt = (TOption*)optBuffer;
	TIPAddMulticast*	addopt = (TIPAddMulticast*)opt->value; 
	
	optReq.flags = T_NEGOTIATE;
	optReq.opt.len = optLength;
	optReq.opt.maxlen = optLength;
	optReq.opt.buf = (UInt8*) optBuffer;
	
	opt->level = INET_IP;
#ifdef _MAC_MACHO
	opt->name = kIP_ADD_MEMBERSHIP;
#else
	opt->name = IP_ADD_MEMBERSHIP;
#endif
	opt->len = optLength;
	opt->status = 0;
	
	addopt->multicastGroupAddress = multicastHost;
	addopt->interfaceAddress = if_addr;
	
	// clear completion flag
	mComplete = false;

	theErr = ::OTOptionManagement(mRef,&optReq, &optReq);

	// wait for completion
	if(!theErr) 
		theErr = OTWait();
	
	if(theErr)
		theErr = HX_MULTICAST_JOIN_ERROR;
		
	return theErr;
	
}

HX_RESULT
OT_UDP::leave_multicast_group(ULONG32 multicastHost, ULONG32 if_addr)
{
	HX_RESULT theErr = HXR_OK;
	
	TOptMgmt 			optReq;
	UInt8	 			optBuffer[ kOTOptionHeaderSize + sizeof(TIPAddMulticast) ];
	ULONG32				optLength = kOTOptionHeaderSize + sizeof(TIPAddMulticast);
	TOption*	 		opt = (TOption*)optBuffer;
	TIPAddMulticast*	addopt = (TIPAddMulticast*)opt->value; 
	
	optReq.flags = T_NEGOTIATE;
	optReq.opt.len = optLength;
	optReq.opt.maxlen = optLength;
	optReq.opt.buf = (UInt8*) optBuffer;
	
	opt->level = INET_IP;
#ifdef _MAC_MACHO
	opt->name = kIP_DROP_MEMBERSHIP;
#else
	opt->name = IP_DROP_MEMBERSHIP;
#endif
	opt->len = optLength;
	opt->status = 0;
	
	addopt->multicastGroupAddress = multicastHost;
	addopt->interfaceAddress = if_addr;
	
	// clear completion flag
	mComplete = false;

	theErr = ::OTOptionManagement(mRef,&optReq, &optReq);

	// wait for completion
	if(!theErr) 
		theErr = OTWait();

	if(theErr)
		return HX_GENERAL_MULTICAST_ERROR;
	
	return HXR_OK;
}


HX_RESULT
OT_UDP::set_broadcast(BOOL enable)
{
	OSStatus		theErr = kOTNoError;
 	mComplete = false;
   	m_bIsBroadcastEnabled = enable;		
 	return HXR_OK;
}
 	

/*----------------------------------------------------------------------------
	UDPNotifyProc 
	
	Open Transport notifier proc for UDP streams.
	
	Entry:	s = pointer to UDP stream.
			code = OT event code.
			result = OT result.
			cookie = OT cookie.
----------------------------------------------------------------------------*/

pascal void OT_UDP::UDPNotifyProc (

	 void *stream, 
	 OTEventCode code,
	 OTResult result, 
	 void *cookie )
	 
{
	OT_UDP* s =  (OT_UDP*) stream;
	
	HXMM_INTERRUPTON();
	s->ProcessCmd(code, result, cookie);
	HXMM_INTERRUPTOFF();
	return;		
}

void
OT_UDP::ProcessCmd(OTEventCode code, OTResult result, void* cookie)
{
	switch (code) 
	{
		case T_DISCONNECT:
			/* Other side has aborted. */
			mOtherSideHasClosed = true;
			mComplete = true;
			mConnectionOpen = FALSE;
			MWDebugPStr("\pT_DISCONNECT");
			
	        if(mCallBack) mCallBack->Func(CONNECT_NOTIFICATION, FALSE);
			break;
			
		case T_ORDREL:
			/* Other side has closed. Close our side if necessary. */
			mOtherSideHasClosed = true;
			mComplete = true;
			mConnectionOpen = FALSE;
			if (mClosing) mRelease = true;
			MWDebugPStr("\pT_ORDREL");
			break;
			
		case T_DATA:
			mDataArrived = TRUE;
			//if(mCallBack) mCallBack->callback_task(HX_UDP_CALLBACK);
			if(mCallBack) mCallBack->Func(READ_NOTIFICATION);
			break;

		case T_BINDCOMPLETE:
		case T_CONNECT:
		case T_PASSCON:
			mComplete = true;
			mCode = code;
			mResult = result;
			mCookie = cookie;
			break;

		case T_OPENCOMPLETE:
			mConnectionOpen = TRUE;
			mComplete = true;
			mCode = code;
			mResult = result;
			mCookie = cookie;
			if(mCallBack) mCallBack->Func(CONNECT_NOTIFICATION);
			break;
		
		case T_GODATA:
			mDataFlowOn = FALSE;
			MWDebugPStr("\pT_GODATA");
			break;

		case T_OPTMGMTCOMPLETE:
			mComplete = true;
			mCode = code;
			mResult = result;
			mCookie = cookie;
			break;
	}

	return;
}

⌨️ 快捷键说明

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