帧开始标志 | 帧大小 | 帧编号 | 帧类型 | 帧数据 |
图3 发送线程工作流程
不妨假设创建的线程名为sendThread,其核心代码实现如下:while(1) { isOK=true; //准备就绪 SuspendThread(sendThread); //挂起线程 isOK=false; //线程正在发送数据 int length=frameLength; //待发数据长度 if(length <50000) {//判断数据是否正常 int n=0; int sendCount=0; while(length >0) { n=send(sock,(char*)imageBuf+sendCount,length,0); //发送数据, //imageBuf是指针,指向待发数据帧 if(n==SOCKET_ERROR) //网络出现异常,则退出线程 break; length-=n; sendCount+=n; } } } |
while(temp!=SOCKET_ERROR) { if(!isStart) {//帧数据是否开始,true表示开始 if(endNum >3) //endNum纪录当前接收未处理的数据 endNum=0; temp=recv(clisock,(char*)(recBuf+endNum),1000,0);//从缓冲区读取数据 startPos=serchStr(temp+endNum); //查找帧开始标志 if(startPos!=-1) { isStart=true; endNum=temp+endNum-startPos-4; memcpy(imageBuf,recBuf+startPos+4,endNum); //保存帧数据 } else{ memcpy(recBuf,recBuf+temp+endNum-3,3);//保存最后三个字节的数据 endNum=3; } } else{ if(endNum <4) {//判定紧跟开始标志的数据,如果小于4表示不能获得帧大小 temp=recv(clisock,(char*)(recBuf),1000,0); //读入数据 memcpy(imageBuf+endNum,recBuf,temp);//保存数据 endNum+=temp; if(endNum <4) continue; frameSize= *((int*)imageBuf);//获得帧大小 if(frameSize <500 || frameSize>50000) {//异常处理(帧大小非法) isStart = false; //丢弃数据重新查找帧开始标志 endNum = 0; continue; } frameSize-=endNum+4; } else{ while(frameSize >0&&temp!=SOCKET_ERROR) {//获得完整帧的剩余数据 temp=recv(clisock,(char*)(imageBuf+endNum),frameSize,0); endNum+=temp; frameSize-=temp; } if(frameSize <=0) {//帧结束置位,解压 isStart=false; endNum=0; deCompress();//判断数据的有效性,调用ICDecompress进行解压 } } } } |