📄 sipreceiver.cxx
字号:
#include "SIPReceiver.h"
#include "MpError.h"
#include "MHError.h"
namespace msip
{
long MsgReceiver::mr_MaxTTL = 60000; //Maximum Time To live 1 minute
//----------------------------------------------------------------------------------
bool
MsgReceiver::RecvBufferItem::equal(const mh323::IPAddress& addr, int id) const
{
if(m_addr < addr) return false;
if(addr < m_addr) return false;
return m_id == id;
}
//----------------------------------------------------------------------------------
MsgReceiver::MsgReceiver(int udp_port, int tcp_port)
: mr_UdpSocket(udp_port),
mr_TcpListener(tcp_port),
mr_EmptyFlag(true),
mr_CurrentID(0)
{
mr_TcpSockets.reserve(64); //preallocate 64 items
if(tcp_port)
{
mr_TcpListener.listen();
}
}
//----------------------------------------------------------------------------------
MsgReceiver::~MsgReceiver()
{
SockArray::iterator it;
for(it = mr_TcpSockets.begin(); it != mr_TcpSockets.end(); ++it)
{
if(it->m_sock)
{
delete it->m_sock;
}
}
}
//----------------------------------------------------------------------------------
void
MsgReceiver::addToFdSet(fd_set * fds) const
{
FD_SET(mr_UdpSocket.getDescriptor(), fds);
FD_SET(mr_TcpListener.getDescriptor(), fds);
SockArray::const_iterator it;
for(it = mr_TcpSockets.begin(); it != mr_TcpSockets.end(); ++it)
{
if(it->m_sock)
{
FD_SET(it->m_sock->getDescriptor(), fds);
}
}
}
//----------------------------------------------------------------------------------
void
MsgReceiver::addMsg(const mh323::IPAddress & addr, int id, const std::mstring & buf)
{
RecvBuffer::iterator it;
for(it = mr_RecvBuffer.begin(); it != mr_RecvBuffer.end(); ++it)
{
if(it->equal(addr, id)) break;
}
if(it == mr_RecvBuffer.end())
{
//Create new
RecvBufferItem itm;
itm.m_addr = addr;
itm.m_id = id;
itm.m_str = buf;
itm.m_tm.setInterval(mr_MaxTTL);
mr_RecvBuffer.push_back(itm);
}
else
{
//Add to existing
it->m_str += buf;
it->m_tm.setInterval(mr_MaxTTL);
}
}
//----------------------------------------------------------------------------------
MsgReceiver::ReceiveResult
MsgReceiver::receive(Message *msg, mh323::IPAddress *addr_from)
{
MsgReceiver::ReceiveResult ret = resNoMessages;
//Erase the message
msg->erase();
std::string::size_type len;
RecvBuffer::iterator it;
for(it = mr_RecvBuffer.begin(); it != mr_RecvBuffer.end(); ++it)
{
std::string::size_type len = Message::findMessageEnd(it->m_str);
if(len != std::string::npos)
{ //There is a complete message
try
{
msg->decode(it->m_str, len);
}
catch(msip::MpSyntaxError &err)
{
msg->erase();
msg->setBadRequest(err.what());
ret = resBadRequest;
}
if(!msg->empty())
{
ret = resReceived;
}
it->m_str.erase(0, len);
break;
}
}
cerr << mr_RecvBuffer.size();
checkReady();
return ret;
}
//----------------------------------------------------------------------------------
bool
MsgReceiver::checkReady()
{
Timer tm;
tm.setCurrent();
RecvBuffer::iterator it;
mr_EmptyFlag = true;
for(it = mr_RecvBuffer.begin(); it != mr_RecvBuffer.end(); )
{
if(it->m_str.find_first_not_of(" \t\n\r") == std::string::npos ||
it->m_tm.outOfInterval(tm))
{
it = mr_RecvBuffer.erase(it);
continue;
}
else
{
if(Message::findMessageEnd(it->m_str) != std::string::npos)
{
mr_EmptyFlag = false;
}
}
++it;
}
return notEmpty();
}
//----------------------------------------------------------------------------------
bool
MsgReceiver::poll(fd_set * fds)
{
if(fds)
{
char buf[recvBufSize + 2];
SockArray::iterator it;
//check udp
if(FD_ISSET(mr_UdpSocket.getDescriptor(), fds))
{
mh323::IPAddress addr;
buf[mr_UdpSocket.recvfrom(buf, recvBufSize, addr)] = 0;
addMsg(addr, 0, buf);
}
//check tcp listener
if(FD_ISSET(mr_TcpListener.getDescriptor(), fds))
{
mh323::TCPSocket * sock = new mh323::TCPSocket;
mr_TcpListener.accept(*sock);
if((++mr_CurrentID) == 0) mr_CurrentID = 1;
//find an empty slot
for(it = mr_TcpSockets.begin(); it != mr_TcpSockets.end(); ++it)
{
if(it->m_sock == 0)
{
it->m_sock = sock;
it->m_id = mr_CurrentID;
break;
}
}
//not foud, add it
if(it == mr_TcpSockets.end())
{
SocketItem sock_itm;
sock_itm.m_id = mr_CurrentID;
sock_itm.m_sock = sock;
mr_TcpSockets.push_back(sock_itm);
}
}
//check opened TCP-connections
for(it = mr_TcpSockets.begin(); it != mr_TcpSockets.end(); ++it)
{
if(it->m_sock)
{
if(FD_ISSET(it->m_sock->getDescriptor(), fds))
{
int nb = 0;
try
{
nb = it->m_sock->recvAll(buf, recvBufSize);
buf[nb] = 0;
addMsg(it->m_sock->getAddress(), it->m_id, buf);
}
catch(mh323::SocketMHError & err)
{
//Socket error means closed remote connection
delete it->m_sock;
it->m_sock = 0;
}
}
}
}
}
return checkReady();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -