




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 场景当用socket进行进程通信,传输数据的时候,会出现以下一些情况:(1)完整的一条消息被系统拆分成几条发送,例如要发送一条消息:Hello World ,却被系统分成两条消息发送,分别为:Hello 和 World。(2)几条独立的消息被系统合成一条消息发送,例如要发送两条消息分别为:a memory from my past和its been a year,却被系统和成一条消息发送:a memory from my pastits been a year。这个时候,需要为socket通信设计一种通信协议,以保证数据的准确性。2 协议格式通信协议设计如下:Head:帧头,2个字节,此处为0xa5a5Type:通信类型,1个字节,范围0x000xffData Length:数据长度,1个字节,即Data的字节总数,Data:实际传输的数据,长度不定CS:校验值,1个字节,type、data length、data三个域所有字节的异或值,实际中并没用到校验End:帧尾,2个字节,此处为0xbeef3 程序设计3.1解析思路假设socket客户端C和服务端S通信,C向S发送消息M1。1、 S收到消息M1。S把消息M1拷贝到缓存Q中,Q为循环队列。假如M1的长度大于Q的剩余空间,则只拷贝剩余空间大小的字节到Q。2、 从Q的当前指针开始,查找帧头。如果找到,则当前指针向后移2个字节位置,继续查找;如果没找到,则删除前1个字节,当前指针向后移1个字节位置,继续查找3、 从Q的当前指针开始,查找。如果Q中至少还剩一个字节,则表示找到,当前指针向后移1个字节位置,否则退出解析。4、 从Q的当前指针开始,查找。如果Q中至少还剩一个字节,则表示找到,当前指针向后移1个字节位置,否则退出解析。5、 从Q的当前指针开始,向后移DataLength个字节位置,查找。如果找到,则从Q中取出一条完整的消息P1,并从Q中删除此消息空间,调用外部的回调函数;否则删除帧头的第一个字节a5,当前指针指向帧头第二个字节a5位置,从步骤2开始,重新一轮解析。3.2数据结构查找策略枚举,用于查找时判断查找帧结构的哪个部位:cppview plaincopy1. typedefenum2. SEARCH_HEAD,3. SEARCH_TYPE,4. SEARCH_LEN,5. /SEARCH_CS,6. SEARCH_END,7. SEARCH_NONE8. cache_strategy;消息结构体,用于存储从缓存中解析出的数据:cppview plaincopy1. typedefstruct2. unsignedchardataSOCKET_MSG_SIZE;/data3. intlen;4. unsignedchartype;5. socket_msg;回调函数,用于从缓存中解析出消息时调用:cppview plaincopy1. typedefvoid(*tp_socket_msg_handle)(intfd,socket_msg*msg,void*args);循环队列,用于缓存接收到的数据:cppview plaincopy1. typedefstruct2. unsignedcharbufSOCKET_MSG_CACHE_SIZE;/bufferforstoringdatareadfromclient3. intfront;4. intrear;5. intcurrent;6. intlen;7. inttag;/markthatwhetherthecacheisfull,1-full,0-notfull8. cache_strategystrategy;9. tp_socket_msg_handlehandle;/callbackfunctiontoinvokewhenamessageisparsedout10. void*args;/externalparameter11. socket_msgrecv_msg;/parsedmessage12. 13. socket_cache;3.3 关键实现1、把接收到的数据存储到缓冲中,并准备解析:cppview plaincopy1. /copytheunparseddatatocache,andparsedthem2. intsocket_msg_pre_parse(3. intfd,4. socket_cache*cache,5. unsignedchar*buf,6. intlen,7. void*args)8. 9. intn=0;10. unsignedchar*p=buf;11. /whenreadingbufferslengthisgreaterthancachesleftlength,12. /weshouldcopymanytimes.13. cache-args=args;14. while(1)15. n=socket_msg_cpy_in(cache,p,len);16. if(n=0)17. returnFALSE;/cacheisfull18. 19. /parseandhandlesocketmessagefromcache20. socket_msg_parse(fd,cache);21. 22. if(n=len)23. returnTRUE;/copycompleted24. 25. /movethepointer26. p=p+n;27. len=len-n;28. 29. 30. returnTRUE;31. 32. 2、递归解析消息:cppview plaincopy1. /parsedthepackageddata,andinvokecallbackfunction2. voidsocket_msg_parse(intfd,socket_cache*cache)3. 4. intcurrent_len;5. intp,q;6. inti;7. intfind;8. 9. if(cache-front=cache-rear&cache-tag=0)10. /D(socketcacheisempty!n);11. return;12. 13. 14. /calculatethecurrentlengthofcache15. if(cache-current=cache-front)16. current_len=cache-len-(cache-current-cache-front);17. 18. else19. current_len=cache-rear-cache-current;20. 21. 22. switch(cache-strategy)23. caseSEARCH_HEAD:/tofindaHeadformatincache24. if(current_lenSOCKET_MSG_HEAD_SIZE)25. return;26. 27. find=FALSE;28. for(i=0;icurrent;30. q=(cache-current+1)%SOCKET_MSG_CACHE_SIZE;31. if(cache-bufp=(SOCKET_MSG_HEAD8)&32. (cache-bufq=(SOCKET_MSG_HEAD&0xff)33. 34. find=TRUE;35. break;/exitforloop36. 37. else38. /currentpointermovetonext39. cache-current=q;40. /deleteoneitem41. cache-front=cache-current;42. cache-len-;43. cache-tag=0;44. 45. 46. 47. if(find=TRUE)48. /move2itemstowardsnext49. cache-current=(cache-current+2)%SOCKET_MSG_CACHE_SIZE;50. /wefoundtheheadformat,goontofindTypebyte51. cache-strategy=SEARCH_TYPE;52. 53. else54. /ifthereisnoheadformat,deletepreviouseitems55. LOGE(socketmessagewithouthead:%x!n,SOCKET_MSG_HEAD);56. /goontofindHeadformat57. cache-strategy=SEARCH_HEAD;58. 59. break;60. 61. caseSEARCH_TYPE:/tofindthetypebyteincache62. if(current_lentype=cache-bufcache-current;67. cache-recv_msg.type=cache-bufcache-current;68. cache-current=(cache-current+1)%SOCKET_MSG_CACHE_SIZE;69. /wefoundTypebyte,goontofindDatalenformat70. cache-strategy=SEARCH_LEN;71. break;72. 73. caseSEARCH_LEN:/tofindthedatalenbyteincache74. if(current_lenbufcache-currentSOCKET_MSG_DATA_SIZE)78. LOGE(thedatalenofmessageoutofsize:%d!n,SOCKET_MSG_DATA_SIZE);79. /deletethefristitema580. /moveback2items81. cache-current=cache-current=2?(cache-current-2):(SOCKET_MSG_CACHE_SIZE-2+cache-current);82. cache-front=cache-current;83. /lengthsub284. cache-len-=2;85. cache-tag=0;86. /goontofindHeadformat87. cache-strategy=SEARCH_HEAD;88. 89. else90. /getthevalueofdatalen91. /cache-data_len=cache-bufcache-current;92. cache-recv_msg.len=cache-bufcache-current;93. cache-current=(cache-current+1)%SOCKET_MSG_CACHE_SIZE;94. /wefounddatalenbyte,goontofindEndformat95. cache-strategy=SEARCH_END;96. 97. break;98. 99. 100. 101. caseSEARCH_END:102. if(current_lenrecv_msg.len+SOCKET_MSG_END_SIZE)103. return;104. 105. /becausewehaveknownthedatabyteslen,sowemovethevery106. /distanceofdatalentoseeifthereisEndformat.107. p=(cache-current+cache-recv_msg.len)%SOCKET_MSG_CACHE_SIZE;108. q=(cache-current+cache-recv_msg.len+1)%SOCKET_MSG_CACHE_SIZE;109. if(cache-bufp=(SOCKET_MSG_END8)&110. (cache-bufq=(SOCKET_MSG_END&0xff)111. socket_msg_cpy_out(cache,cache-recv_msg.data,cache-current,cache-recv_msg.len);112. if(cache-handle!=NULL)113. /cache-handle(fd,cache-buf+cache-data_index,cache-data_len);114. cache-handle(fd,&cache-recv_msg,cache-args);115. 116. /deleteallpreviousitems117. cache-current=(q+1)%SOCKET_MSG_CACHE_SIZE;118. cache-front=cache-current;119. cache-len-=(cache-recv_msg.len+SOCKET_MSG_FORMAT_SIZE);120. cache-tag=0;121. 122. 123. else124. LOGE(socketmessagewithoutend:%x!n,SOCKET_MSG_END);125. /deletethefristitema5126. /moveback3items127. cache-current=cache-current=3?(cache-current-3):(SOCKET_MSG_CACHE_
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 美食广场整体承包经营合同范本
- 中医护理三因制宜
- 餐饮业股权投资合作与风险控制合同
- 商务代驾服务委托合同
- 铁路快运代理服务合作协议书
- 肠胀气病人的护理
- 垃圾处理设施安全责任承包管理合同
- 肿瘤患者出院健康指导
- 餐饮品牌商标使用权及加盟管理合同
- 餐饮企业加盟店经营数据保密协议
- 《颅骨修补术》课件
- python入门培训课件
- 劳模创新工作室汇报材料方案
- 化验室的相关管理要点
- 人教版2024年六年级语文下册期末考试摸底检测
- 西南民族大学:人工智能赋能课程建设的逻辑与路径
- (外研版3起)英语五年级上册单词字帖书写练习(手写体)高清打印版
- 规章制度之培训学校教学管理制度
- 江苏省盐城市2023年七年级下册《数学》期末试卷与参考答案
- 安徽省安庆市铜陵市池州市2023-2024学年高二下学期7月三市联合期末检测数学试题2
- 新教科版小学科学六年级上册全册教案(2022年春修订)
评论
0/150
提交评论