视频监控安防平台--国标28181-2016版本TCP码流沾包流程

来源:互联网 发布:java jsonarray 类 编辑:程序博客网 时间:2024/05/27 14:13

视频安防监控平台-国标28181-2016版本TCP码流沾包流程 (如需交流可联系QQ:123011785)

由于28181规定tcp码流要使用RFC4571,通俗点就是每个包的格式为 长度(2个字节)+RTP头(12个字节)+数据模式,然后自己在根据这个格式进行沾包处理。

1、首先明确GB28181的TCP码流遵循的是RFC4571(RTP OVER TCP),具体类型

    0                   1                   2                   3    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1    ---------------------------------------------------------------   |             LENGTH            |  RTP or RTCP packet ...       |    ---------------------------------------------------------------        Figure 1: The bit field definition of the framing method

2、详细协议文档可以参考《rfc4571.Framing-Real-time-Transport-Protocol-(RTP)-and-RTP-Control-Protocol-(RTCP)-Packets-over-Conn.pdf》文档


3、下面我把沾包的代码基本流程放上来, 目前已经在很多项目上面用,实用情况比较好

void StreamThread::StickyTcpStramPacket(UINT8 *pData, int TcpRecvLen)   //接收每个tcp的数据和长度{if (pData == NULL || TcpRecvLen <= 0){printf("%s :Tcp Recv Data Error!!", __FUNCTION__);return;}UINT8* pBuff = pData;do{if (0 == m_sizeOfTcpRecvBufTmp){//长度的字段分开,需要保留最好一个字节, 确保每一个包都完整的接收if (TcpRecvLen < TCP_STRAM_HEADER_LEN){printf("TcpRecvLen(%d) < TCP_STRAM_HEADER_LEN(2) !!!!!!!!!!pBuff[0]:0x%02x", TcpRecvLen, pBuff[0]);if ((TcpRecvLen > 0) && (m_HeadTmplen <= 0)){memcpy(m_pHeadTmpBuff, pBuff, TcpRecvLen);m_HeadTmplen = TcpRecvLen;}break;}if ((m_HeadTmplen > 0) && (m_pHeadTmpBuff != NULL)){memcpy(m_pHeadTmpBuff+m_HeadTmplen, pData, TcpRecvLen);//针对buff重新赋值;pBuff = m_pHeadTmpBuff;TcpRecvLen += m_HeadTmplen;m_HeadTmplen = 0;}m_sizeOfTcpRecvPacketBuf = htons(*( (UINT16 *)&pBuff[0] ));pBuff += TCP_STRAM_HEADER_LEN;TcpRecvLen -= TCP_STRAM_HEADER_LEN;m_sizeOfTcpRecvBufTmp = m_sizeOfTcpRecvPacketBuf;m_pTcpRecvPacketBuf = (UINT8 *)malloc(m_sizeOfTcpRecvPacketBuf*2);m_pTcpRecvBufTmp = m_pTcpRecvPacketBuf;}if (TcpRecvLen <= 0){break;} //已接收的包数据长度 < 包数据长度 = 一个不完整的包 if (TcpRecvLen < m_sizeOfTcpRecvBufTmp){memcpy(m_pTcpRecvBufTmp, pBuff, TcpRecvLen);m_pTcpRecvBufTmp += TcpRecvLen;m_sizeOfTcpRecvBufTmp -= TcpRecvLen;pBuff += TcpRecvLen;TcpRecvLen  -= TcpRecvLen;}else{    //已接收的包数据长度 == 包数据长度 = 一个完整的包  //已接收的包数据长度 > 包数据长度  = 至少有一个完整的包 + 至少一个数据片段 memcpy(m_pTcpRecvBufTmp, pBuff, m_sizeOfTcpRecvBufTmp);pBuff += m_sizeOfTcpRecvBufTmp;TcpRecvLen -= m_sizeOfTcpRecvBufTmp;UINT32 SSrc = ntohl( *( (UINT32 *)&m_pTcpRecvPacketBuf[8]) );if (m_tcprecvssrc <= 0){m_tcprecvssrc = SSrc;}//如果ssrc不一致, 表示解析失败if (m_tcprecvssrc != SSrc){printf("vvvvvvv%d recvpacklen:%d\n", TcpRecvLen, m_sizeOfTcpRecvPacketBuf);//freeif (m_pTcpRecvPacketBuf != NULL){free(m_pTcpRecvPacketBuf);m_pTcpRecvPacketBuf = NULL;}m_sizeOfTcpRecvBufTmp = 0;break;}TcpStreamPacket tcppacket;tcppacket.nLength = m_sizeOfTcpRecvPacketBuf;tcppacket.pData = (UINT8*)new char[m_sizeOfTcpRecvPacketBuf+1];memcpy(tcppacket.pData, m_pTcpRecvPacketBuf, tcppacket.nLength);if (tcppacket.nLength > 0){tcppacket.pData[tcppacket.nLength] = '\0';}m_listTcpStreamPacket.push_back(tcppacket);#if 1//freeif (m_pTcpRecvPacketBuf != NULL){free(m_pTcpRecvPacketBuf);m_pTcpRecvPacketBuf = NULL;}m_sizeOfTcpRecvBufTmp = 0;#else//memset(m_pTcpRecvBufTmp, 0, sizeof(m_pTcpRecvBufTmp));m_pTcpRecvBufTmp = NULL;m_sizeOfTcpRecvBufTmp = 0;#endif}}while(TcpRecvLen > 0);}


协议文档《rfc4571.Framing-Real-time-Transport-Protocol-(RTP)-and-RTP-Control-Protocol-(RTCP)-Packets-over-Conn.pdf》下载地址:

http://download.csdn.net/download/songxiao1988918/10148885


阅读全文
1 0