📄 ot_udp.cp
字号:
case kOTLookErr: { OSStatus lookErr = ::OTLook(mRef); TUDErr UDErr; if(lookErr == T_UDERR) { 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_RESULTOT_UDP::read (void *data, UINT16 *len){ return HXR_NOTIMPL;}HX_RESULTOT_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_RESULTOT_UDP::listen (UINT16 backlog){ return(HXR_INVALID_OPERATION);}*/ HX_RESULTOT_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_RESULTOT_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_RESULTOT_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_RESULTOT_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; }voidOT_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 + -