C++ 实现网络socket拆包组包处理
网络连接使用UDP,接收码流数据进行处理
//数据结构:
typedef struct DispensePkt { unsigned int lenght; unsigned int cntpkt; unsigned int index; unsigned long long pts; char data[1400]; }DispensePkt; //线程处理网络数据, 进行组包处理 while (running) { if(step ==0){ gettimeofday(&tss,NULL); start = (tss.tv_sec*1000 + tss.tv_usec/1000); } // 接收UDP数据 s32ReadLen = mUnicast.RkRecvfrom((unsigned char*)&_dispense_pkt,sizeof(DispensePkt)); if(s32ReadLen <= 0){ //printf("%s %d \n",__FUNCTION__,__LINE__); usleep(100); continue; } if(_dispense_pkt.index == 0){ index = 0; frameLen =0; } if(index != _dispense_pkt.index){ time_t timep; time (&timep); printf("date: %s idx(%d) %d pkt(%d) len(%d)\n",ctime(&timep),index,_dispense_pkt.index ,_dispense_pkt.cntpkt,_dispense_pkt.lenght); cnt = 0; offset = 0; index = 0; continue; } index++; if(offset <= s32MinBufSize){ if(s32ReadLen == sizeof(DispensePkt)){ memcpy(fBuf+offset,_dispense_pkt.data,MEDIA_VIDEO_PAKET_LEN); frameLen += MEDIA_VIDEO_PAKET_LEN; offset += MEDIA_VIDEO_PAKET_LEN; } else if(s32ReadLen < sizeof(DispensePkt)){ memcpy(fBuf+offset,_dispense_pkt.data,MEDIA_VIDEO_PAKET_LEN - sizeof(DispensePkt) + s32ReadLen); frameLen += MEDIA_VIDEO_PAKET_LEN - sizeof(DispensePkt) + s32ReadLen; offset += MEDIA_VIDEO_PAKET_LEN - sizeof(DispensePkt) + s32ReadLen; } } if(frameLen >= _dispense_pkt.lenght){ cnt++; if(cnt == _dispense_pkt.cntpkt){ // 完整一帧处理 //printf("--- %d %d \n",_dispense_pkt.lenght,frameLen); total += frameLen; step++; cnt = 0; offset = 0; pthread_mutex_lock(&m_mutex); MB_BLK buffer = RK_NULL; RK_S32 usersize = _dispense_pkt.lenght; RK_S8 *userdata = (RK_S8 *)malloc(usersize); memcpy(userdata,fBuf,usersize); stMbExtConfig.pFreeCB = user_data_callback; stMbExtConfig.pOpaque = userdata; stMbExtConfig.pu8VirAddr = (RK_U8*)userdata; stMbExtConfig.u64Size = usersize; //usersize = _dispense_pkt.lenght; //stMbExtConfig.u64Size = usersize; RK_MPI_SYS_CreateMB(&buffer, &stMbExtConfig); stStream.u64PTS = pts; stStream.pMbBlk = buffer; stStream.u32Len = usersize; stStream.bEndOfFrame = RK_TRUE; stStream.bBypassMbBlk = RK_TRUE; //for(int i=0;i< DECODE_MAX_NUM;i++){ // 完整一帧数据给解码器 if(RK_MPI_VDEC_SendStream(chnId, &stStream, 33333)==RK_SUCCESS) fps++; //} pts += 16667; RK_MPI_MB_ReleaseMB(stStream.pMbBlk); pthread_mutex_unlock(&m_mutex); } frameLen = 0; } gettimeofday(&tse, NULL); end = (tse.tv_sec*1000 + tse.tv_usec/1000); if((end-start) >= 1000){ if(fps<60) printf("chnId(%d) fps: %d step: %d rate: %d kbps \n",chnId,fps,step,total*8/1024); fps = 0; total = 0; step = 0; } }
越努力,越幸运
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端