📄 hxsymbiantcpsock.cpp
字号:
/*
* IHXTCPSocket methods
*
* Network addresses and ports are in native byte order
*
*/
STDMETHODIMP HXSymbianTCPSocket::Init(THIS_
IHXTCPResponse* /*IN*/ pTCPResponse)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Init()\n"));
HX_RELEASE(m_pResponse);
m_pResponse = pTCPResponse;
if (m_pResponse)
m_pResponse->AddRef();
return (m_pResponse) ? HXR_OK : HXR_FAILED;
}
STDMETHODIMP HXSymbianTCPSocket::SetResponse(THIS_
IHXTCPResponse* pTCPResponse)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::SetResponse()\n"));
HX_RELEASE(m_pResponse);
m_pResponse = pTCPResponse;
if (m_pResponse)
m_pResponse->AddRef();
return (m_pResponse) ? HXR_OK : HXR_FAILED;
}
STDMETHODIMP HXSymbianTCPSocket::Bind(THIS_
UINT32 ulLocalAddr,
UINT16 nPort)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Bind(%08lx, %u)\n",
ulLocalAddr, nPort));
HX_RESULT res = HXR_FAILED;
TInetAddr addr(ulLocalAddr, nPort);
if ((m_state == tcpInitialized) &&
(m_socket.Bind(addr) == KErrNone))
{
m_state = tcpBound;
res = HXR_OK;
}
return res;
}
/*
* pDestination is a string containing host name or dotted-ip notation
*/
STDMETHODIMP HXSymbianTCPSocket::Connect(THIS_
const char* pDestination,
UINT16 nPort)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Connect('%s', %u)\n",
pDestination, nPort));
HX_RESULT res = HXR_FAILED;
if (m_state == tcpInitialized)
Bind(0, 0);
if (m_state == tcpBound)
{
m_state = tcpResolving;
m_nConnectPort = nPort;
res = m_pResolver->GetHostByName(pDestination);
if (HXR_OK != res)
{
m_state = tcpBound;
}
}
return res;
}
STDMETHODIMP HXSymbianTCPSocket::Read(THIS_ UINT16 Size)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Read(%u)\n", Size));
HX_RESULT res = HXR_FAILED;
HX_ASSERT(m_state == tcpConnected);
if ((m_state == tcpConnected) && (!m_pReader->IsActive()))
{
res = DoRead(Size);
}
return res;
}
STDMETHODIMP HXSymbianTCPSocket::Write(THIS_ IHXBuffer* pBuffer)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Write()\n"));
HX_RESULT res = HXR_FAILED;
HX_ASSERT(m_state == tcpConnected);
if ((m_state == tcpConnected) && pBuffer)
{
if (m_pWriter->IsActive())
{
// A write is in progress. Add the buffer
// to the write list
pBuffer->AddRef();
LISTPOSITION listRet = m_writeList.AddTail(pBuffer);
if( listRet == NULL )
{
res = HXR_OUTOFMEMORY;
HX_RELEASE(pBuffer);
}
}
else
{
// Do the write now
m_pWriter->Write(m_socket, pBuffer);
}
res = HXR_OK;
}
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.
*/
STDMETHODIMP HXSymbianTCPSocket::WantWrite(THIS)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::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 HXSymbianTCPSocket::GetForeignAddress(THIS_ REF(ULONG32) lAddress)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetForeignAddress()\n"));
HX_RESULT res = HXR_FAILED;
if (m_state == tcpConnected)
{
TInetAddr addr;
m_socket.RemoteName(addr);
lAddress = (ULONG32)addr.Address();
res = HXR_OK;
}
return res;
}
STDMETHODIMP HXSymbianTCPSocket::GetLocalAddress(THIS_ REF(ULONG32) lAddress)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetLocalAddress()\n"));
HX_RESULT res = HXR_FAILED;
if ((m_state != tcpNotInitialized) &&
(m_state != tcpInitialized))
{
TInetAddr addr;
m_socket.LocalName(addr);
lAddress = (ULONG32)addr.Address();
res = HXR_OK;
}
return res;
}
/************************************************************************
* Method:
* IHXTCPSocket::GetForeignPort
* Purpose:
* Returns the port of the other end of the TCP socket in local
* host order.
*/
STDMETHODIMP HXSymbianTCPSocket::GetForeignPort(THIS_ REF(UINT16) port)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetForeignPort()\n"));
HX_RESULT res = HXR_FAILED;
if (m_state == tcpConnected)
{
TInetAddr addr;
m_socket.RemoteName(addr);
port = addr.Port();
res = HXR_OK;
}
return res;
}
STDMETHODIMP HXSymbianTCPSocket::GetLocalPort(THIS_ REF(UINT16) port)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetLocalPort()\n"));
HX_RESULT res = HXR_FAILED;
if ((m_state != tcpNotInitialized) &&
(m_state != tcpInitialized))
{
port = m_socket.LocalPort();
res = HXR_OK;
}
return res;
}
STDMETHODIMP HXSymbianTCPSocket::SetOption(THIS_
HX_SOCKET_OPTION option,
UINT32 ulValue)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::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:
if (m_socket.SetOpt(KSoReuseAddr, KSOLSocket, ulValue) == KErrNone)
{
res = HXR_OK;
}
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:
res = HXR_FAILED;
break;
};
}
return res;
}
HX_RESULT HXSymbianTCPSocket::GetHostByNameDone(HX_RESULT status,
ULONG32 ulAddr)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::ResolveDone(%ld, %08lx)\n",
status, ulAddr));
HX_ASSERT(m_state == tcpResolving);
DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
if (m_state == tcpResolving)
{
if (status == HXR_OK)
{
m_pConnector->Connect(m_socket, ulAddr, m_nConnectPort);
m_state = tcpConnecting;
}
else if (m_pResponse)
{
m_pResponse->ConnectDone(status);
m_state = tcpBound;
}
}
return HXR_OK;
}
void HXSymbianTCPSocket::OnConnect(HX_RESULT status)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::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 HXSymbianTCPSocket::OnWriteDone(HX_RESULT status)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::OnWriteDone(%ld)\n", status));
DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
if (status == HXR_OK)
{
if (m_writeList.GetCount() > 0)
{
// Write the next buffer in the list
IHXBuffer* pBuffer = (IHXBuffer*)m_writeList.RemoveHead();
m_pWriter->Write(m_socket, pBuffer);
HX_RELEASE(pBuffer);
}
// Signal WriteReady() if we don't have any
// writes pending and the response object
// wants these calls
if (!m_pWriter->IsActive() && m_bWantWrite && m_pResponse)
{
m_pResponse->WriteReady(HXR_OK);
}
}
else
{
CloseConnection(status);
}
}
void HXSymbianTCPSocket::OnReadDone(HX_RESULT status, IHXBuffer* pBuffer)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::OnReadDone(%ld)\n", status));
DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
if (m_pResponse)
{
// We assume error reporting/handling is done in the response object
// via the value of status passed here.
m_pResponse->ReadDone(status, pBuffer);
}
if (status != HXR_OK)
{
CloseConnection(status);
}
}
HX_RESULT HXSymbianTCPSocket::DoRead(UINT16 size)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::DoRead(%u)\n", size));
HX_RESULT res = HXR_FAILED;
if (m_pReader)
{
res = m_pReader->Read(m_socket, size);
}
return res;
}
void HXSymbianTCPSocket::CloseConnection(HX_RESULT status)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::CloseConnection(%ld)\n",
status));
if (m_state != tcpNotInitialized)
{
// Cancel any connector
if (m_pConnector->IsActive())
{
m_socket.CancelConnect();
m_pConnector->Cancel();
}
// Cancel writer
if (m_pWriter->IsActive())
{
m_socket.CancelWrite();
m_pWriter->Cancel();
}
if (m_pReader->IsActive())
{
m_socket.CancelRecv();
m_pReader->Cancel();
}
// Clear the writer list
while (m_writeList.GetCount() > 0)
{
// Write the next buffer 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 = tcpInitialized;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -