视频监控安防平台-GB28181-2016版-sip协议tcp沾包流程
由于GB28181设计的时候基本很少使用tcp包,只有在资源推送和录像检索查询返回的时候才会使用的tcp消息,下面简单说一下tcp消息使用,首先建立一个tcp短连接,然后将消息发送出去,消息长度尽量在2M以下。
下面粘贴一段sip消息tcp沾包的代码,希望对您有所帮助.
void CUvSocketTransMgr::sip_tcp_sticky_packet(TUvSocketItem * pSocketItem, const char *pData, int len, const char *pSrcIP, int SrcPort,const char* pDestIP,int DestPort)
{
if(len > 0)
{
char *end_sip = NULL;
char *cl_header = NULL;
int cl_size = 0;
if(pSocketItem->pTcpRecvData != NULL)
{
/* concat old data with new data */
pSocketItem->pTcpRecvData = (char *)realloc(pSocketItem->pTcpRecvData, pSocketItem->nTcpRecvLen+len+1);
if(NULL == pSocketItem->pTcpRecvData)
{
printf("realloc pTcpRecvData failed!\n");
pSocketItem->nTcpRecvLen = 0;
return;
}
strncpy(pSocketItem->pTcpRecvData+pSocketItem->nTcpRecvLen, pData, len);
pSocketItem->pTcpRecvData[pSocketItem->nTcpRecvLen+len] = '\0';
pSocketItem->nTcpRecvLen = pSocketItem->nTcpRecvLen + len;
}
if(NULL == pSocketItem->pTcpRecvData)
{
pSocketItem->pTcpRecvData = (char *)malloc(len+1);
if(pSocketItem->pTcpRecvData != NULL)
{
memset(pSocketItem->pTcpRecvData, 0, len+1);
}
strncpy(pSocketItem->pTcpRecvData, pData, len);
pSocketItem->pTcpRecvData[len] = '\0';
pSocketItem->nTcpRecvLen = len;
}
end_sip = strstr(pSocketItem->pTcpRecvData, "\r\n\r\n");
while(end_sip != NULL)
{
cl_header = mystrcasestr(pSocketItem->pTcpRecvData, "\ncontent-length ");
if (cl_header == NULL || cl_header > end_sip)
cl_header = mystrcasestr(pSocketItem->pTcpRecvData,"\ncontent-length:");
if (cl_header == NULL || cl_header > end_sip)
cl_header =mystrcasestr(pSocketItem->pTcpRecvData,"\r\nl ");
if (cl_header == NULL || cl_header > end_sip)
cl_header =mystrcasestr(pSocketItem->pTcpRecvData,"\r\nl:");
if (cl_header != NULL && cl_header < end_sip)
cl_header = strchr(cl_header, ':');
if (cl_header == NULL || cl_header >= end_sip)
{
/* remove data up to crlfcrlf and restart */
memmove(pSocketItem->pTcpRecvData, end_sip+4,pSocketItem->nTcpRecvLen -(end_sip + 4 -pSocketItem->pTcpRecvData) + 1);
pSocketItem->nTcpRecvLen = pSocketItem->nTcpRecvLen - (end_sip +4 -pSocketItem->pTcpRecvData);
pSocketItem->pTcpRecvData = (char *)realloc(pSocketItem->pTcpRecvData, pSocketItem->nTcpRecvLen+1);
if(pSocketItem->pTcpRecvData == NULL)
{
pSocketItem->nTcpRecvLen = 0;
break;
}
end_sip =strstr(pSocketItem->pTcpRecvData,"\r\n\r\n");
continue; /* and restart from new CRLFCRLF */
}
/* header content-length was found before CRLFCRLF -> all headers are available */
cl_header++; /* after ':' char */
cl_size = atoi(cl_header);
if (cl_size == 0|| (cl_size >0 && (end_sip + 4 + cl_size <=pSocketItem->pTcpRecvData+pSocketItem->nTcpRecvLen)))
{
uv_mutex_lock(&mutex_data_);
RecvPacketCallBack(pSocketItem->socketfd,pSocketItem->pTcpRecvData, (end_sip + 4 + cl_size -pSocketItem->pTcpRecvData),\
pSrcIP,SrcPort,pDestIP,DestPort, true);
uv_mutex_unlock(&mutex_data_);
if (pSocketItem->nTcpRecvLen -(end_sip + 4 + cl_size -pSocketItem->pTcpRecvData) == 0)
{
end_sip = NULL;
pSocketItem->nTcpRecvLen = 0;
free(pSocketItem->pTcpRecvData);
pSocketItem->pTcpRecvData = NULL;
continue;
}
memmove(pSocketItem->pTcpRecvData,end_sip + 4 + cl_size, pSocketItem->nTcpRecvLen -(end_sip + 4 + cl_size -pSocketItem->pTcpRecvData) + 1);
pSocketItem->nTcpRecvLen = pSocketItem->nTcpRecvLen - (end_sip +4 +cl_size -pSocketItem->pTcpRecvData);
pSocketItem->pTcpRecvData = (char *)realloc(pSocketItem->pTcpRecvData,pSocketItem->nTcpRecvLen + 1);
if (pSocketItem->pTcpRecvData == NULL)
{
printf("realloc pSocketItem->pTcpRecvDatapSocketItem->pTcpRecvDatapSocketItem->pTcpRecvData!!\n");
pSocketItem->nTcpRecvLen = 0;
break;
}
end_sip =strstr(pSocketItem->pTcpRecvData,"\r\n\r\n");
continue; /* and restart from new CRLFCRLF */
}
/* uncomplete SIP message */
end_sip = NULL;
}
if (pSocketItem->nTcpRecvLen== 0)
{
/* all data consumed are reallocation error ? */
return;
}
}
else if(len< 0)
{
printf("Could not read socket (%d)- close it\n",pSocketItem->socketfd);
//DelSocketItem(pSocketItem);
//close(pSocketItem->sock);
}
else if (len == 0)
{
printf("End of stream (read 0 byte from %s:%i)\n", pSocketItem->srcip, pSocketItem->srcport);
//DelSocketItem(pSocketItem);
//close(pSocketItem->sock);
}
else
{
printf("Dummy SIP message received (size=%d)\n", len);
}
}