📄 hxopwavetcpsock.cpp
字号:
DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::Write()\n")); HX_RESULT res = HXR_OK; if (!pBuffer) { res = HXR_INVALID_PARAMETER; } //OpDPRINTF("Write: this=%p, lwsize=%d, bread=%d, newwritesize=%d, bwrite=%d\n", this, m_ulBytesLeftToWrite, m_bReadable, pBuffer->GetSize(), m_bWritable); UCHAR* pBufData = pBuffer->GetBuffer(); if (SUCCEEDED(res) && (m_state == tcpConnected)) { /// First add to our list pBuffer->AddRef(); m_writeList.AddTail(pBuffer); /// decide if we need to do a write /// because last time when it is ready to write, there is no data /// to be written. if (m_bWritable) { if (!m_pWriteBuffer) { m_pWriteBuffer = (IHXBuffer*)m_writeList.RemoveHead(); m_ulBytesLeftToWrite = m_pWriteBuffer->GetSize(); } res =DoWrite(); if (SUCCEEDED(res)) { m_bWritable = FALSE; } } } return res;}/// This is working method to do actual write from/// the m_pWriteBuffer which is guranteed to have data to be written/// and the socket is ready to accept dataHX_RESULT HXOpwaveTCPSocket::DoWrite(){ HX_RESULT res = HXR_OK; UCHAR* pBufData = m_pWriteBuffer->GetBuffer(); size_t ulActualWritten = write(pBufData, m_ulBytesLeftToWrite); HX_ASSERT(m_ulBytesLeftToWrite >= ulActualWritten); //OpDPRINTF("DoWrite, this=%p, written%d, write=%d\n\n",this, ulActualWritten, m_ulBytesLeftToWrite); m_ulBytesLeftToWrite -= ulActualWritten; if (m_ulBytesLeftToWrite > 0) { // more left in this m_pWriteBuffer to be written out UCHAR* pLeftData = new UCHAR[m_ulBytesLeftToWrite]; if (!pLeftData) { res = HXR_OUTOFMEMORY; OnWriteDone(res); return res; } memcpy(pLeftData, pBufData+ulActualWritten, m_ulBytesLeftToWrite); m_pWriteBuffer->Set(pLeftData, m_ulBytesLeftToWrite); delete pLeftData; } return res;}/************************************************************************ * Method: * IHXTCPSocket::WantWrite * Purpose: * This method is called when you wish to write a large amount of * data. If you are only writing small amounts of data, you can * just call Write (all data not ready to be transmitted will be * buffered on your behalf). When the TCP channel is ready to be * written to, the response interfaces WriteReady method will be * called. */STDMETHODIMPHXOpwaveTCPSocket::WantWrite(THIS){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::WantWrite()\n")); m_bWantWrite = TRUE; return HXR_OK;}/************************************************************************ * Method: * IHXTCPSocket::GetForeignAddress * Purpose: * Returns the address of the other end of the TCP socket as a * ULONG32 in local host order */STDMETHODIMP HXOpwaveTCPSocket::GetForeignAddress(THIS_ REF(ULONG32) lAddress){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::GetForeignAddress()\n")); /// OpSocket's DNS should make this better HX_RESULT res = HXR_OK; if (m_state == tcpConnected) { lAddress = m_ipDest; } return res;}STDMETHODIMP HXOpwaveTCPSocket::GetLocalAddress(THIS_ REF(ULONG32) lAddress){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::GetLocalAddress()\n")); HX_RESULT res = HXR_OK; lAddress = m_ulLocalAddr; return res;}/************************************************************************ * Method: * IHXTCPSocket::GetForeignPort * Purpose: * Returns the port of the other end of the TCP socket in local * host order. */STDMETHODIMPHXOpwaveTCPSocket::GetForeignPort(THIS_ REF(UINT16) port){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::GetForeignPort()\n")); /// Until OpSocket has DNS, this is not appropriately implemented HX_RESULT res = HXR_OK; if (m_state == tcpConnected) { port = m_nConnectPort; } else { res = HXR_FAILED; } return res;}STDMETHODIMPHXOpwaveTCPSocket::GetLocalPort(THIS_ REF(UINT16) port){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::GetLocalPort()\n")); HX_RESULT res = HXR_OK; if ((m_state != tcpNotInitialized) && (m_state != tcpInitialized)) { port = m_nLocalPort; } return res;}STDMETHODIMP HXOpwaveTCPSocket::SetOption(THIS_ HX_SOCKET_OPTION option, UINT32 ulValue){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::SetOption(%d, %lu)\n", option, ulValue)); HX_RESULT res = HXR_FAILED; if (m_state == tcpNotInitialized) { switch(option) { case HX_SOCKOPT_REUSE_ADDR: case HX_SOCKOPT_REUSE_PORT: //// OpSocket doesn't support set socket options { res = HXR_NOTIMPL; } break; case HX_SOCKOPT_BROADCAST: case HX_SOCKOPT_SET_RECVBUF_SIZE: case HX_SOCKOPT_SET_SENDBUF_SIZE: case HX_SOCKOPT_MULTICAST_IF: res = HXR_UNEXPECTED; break; default: break; } } return res;}HX_RESULTHXOpwaveTCPSocket::GetHostByNameDone(HX_RESULT status, ULONG32 ulAddr){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::ResolveDone(%ld, %08lx)\n", status, ulAddr)); HX_ASSERT( m_state == tcpResolving); if (SUCCEEDED(status)) { m_ipDest = ulAddr; m_state = tcpConnecting; connect(m_nLocalPort, m_nConnectPort, m_ipDest); /* char* stopstring = NULL; UINT32 segVal = 0; segVal = strtoul(pDestination, &stopstring, 10); m_ipDest = segVal << 24; pDestination = stopstring + 1; segVal = strtoul(pDestination, &stopstring, 10); m_ipDest += (segVal << 16); pDestination = stopstring + 1; segVal = strtoul(pDestination, &stopstring, 10); m_ipDest += (segVal << 8); pDestination = stopstring + 1; segVal = strtoul(pDestination, &stopstring, 10); m_ipDest += segVal; connect(m_nLocalPort, nPort, m_ipDest); //OpDPRINTF("Connect: this=%p, localPort=%d,remotePort=%d,desIP=%d\n", this, m_nLocalPort, nPort, m_ipDest); */ m_bWritable = FALSE; m_bReadable = FALSE; } return status;}void HXOpwaveTCPSocket::OnConnect(HX_RESULT status){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::OnConnect(%ld)\n",status)); HX_ASSERT(m_state == tcpConnecting); DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this); if (status == HXR_OK) { m_state = tcpConnected; } else { m_state = tcpBound; } if (m_pResponse) { m_pResponse->ConnectDone(status); }}void HXOpwaveTCPSocket::OnWriteDone(HX_RESULT status){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::OnWriteDone(%ld)\n", status)); DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this); if (status == HXR_OK) { HX_RELEASE(m_pWriteBuffer); if (m_writeList.GetCount() > 0) { m_pWriteBuffer = (IHXBuffer*)m_writeList.RemoveHead(); m_ulBytesLeftToWrite = m_pWriteBuffer->GetSize(); } // Signal WriteReady() if we don't have any // writes pending and the response object // wants these calls if (m_bWantWrite && m_pResponse) { m_pResponse->WriteReady(HXR_OK); } } else { CloseConnection(status); }}void HXOpwaveTCPSocket::OnReadDone(HX_RESULT status, IHXBuffer* pBuffer){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::OnReadDone(%ld)\n", status)); DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this); if (m_pResponse) { m_pResponse->ReadDone(status, pBuffer); } if (status != HXR_OK) { CloseConnection(status); }}void HXOpwaveTCPSocket::CloseConnection(HX_RESULT status){ DPRINTF(D_TCPSOCKET, ("HXOpwaveTCPSocket::CloseConnection(%ld)\n", status)); if (m_state != tcpNotInitialized) { close(true); } // Clear the writer list while (m_writeList.GetCount() > 0) { // Release all the left unsent buffers in the list IHXBuffer* pBuffer = (IHXBuffer*)m_writeList.RemoveHead(); HX_RELEASE(pBuffer); } if ((m_state != tcpInitialized) && m_pResponse) { m_pResponse->Closed(HXR_OK); } m_state = tcpNotInitialized;}void HXOpwaveTCPSocket::onReadable(OpSocketEvent *pSocketEvent){ HX_RESULT res = HXR_OK; m_bReadable = TRUE; //OpDPRINTF("onReadable: this=%p, mrsize=%d, bread=%d, state=%d, bwrite=%d\n", this, m_ulReadSize, m_bReadable, m_state, m_bWritable); if (m_ulReadSize > 0) { /// avoid recursion that might occur because /// OnReadDone call in DoRead invoke ::Read again m_bReadable = FALSE; DoRead(); }}void HXOpwaveTCPSocket::onWritable(OpSocketEvent *pSocketEvent){ HX_RESULT res = HXR_OK; m_bWritable = TRUE; //OpDPRINTF("onWritable: this=%p, mrsize=%d, bread=%d, lwsize=%d, bwrite=%d\n", this, m_ulReadSize, m_bReadable, m_ulBytesLeftToWrite, m_bWritable); if (m_state == tcpConnecting) { /// Since Openwave OpSocket's api is designed to have kWritable as the first /// event sending back to clients, so we first respond to core for connection /// status OpSocketEvent::Condition sockCond = pSocketEvent->getCondition(); HX_RESULT status = sockCond == OpSocketEvent::kException ? HXR_NET_CONNECT : HXR_OK; OnConnect(status); } /// Normal write process /// Call OnWriteDone for handling the notification of last write if (m_ulBytesLeftToWrite == 0) { /// Notify last writing is completely done OnWriteDone(res); } /// Do the next writing if (m_pWriteBuffer && m_ulBytesLeftToWrite > 0) { if (DoWrite() == HXR_OK) { m_bWritable = FALSE; } } }void HXOpwaveTCPSocket::onException(OpSocketEvent *pSocketEvent){ OpSocketEvent::Exception except = pSocketEvent->getException();} #if 0// Don't need it for the time being because// all the cases are handled by the above three callbacks.bool HXOpwaveTCPSocket::onEvent(OpEvent& ev){ OpSocketEvent* pSockEvt = NULL; if ( (pSockEvt = OpSocketEvent::Cast(&ev)) != NULL) { HX_RESULT status = pSockEvt->getCondition() == OpSocketEvent::kException ? HXR_NET_CONNECT : HXR_OK; OnConnect(status); return true; } return OpEventSink::onEvent(ev);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -