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

📄 sipreceiver.cxx

📁 一个SIP协议栈
💻 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 + -