免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6941 | 回复: 28
打印 上一主题 下一主题

请教:如何收取tcp协议包? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-22 17:53 |只看该作者 |倒序浏览
现在在收取tcp包的时候出了问题.收取的包为某种协议(不能修改),格式如下:

  1. method:xxx
  2. from:xxx
  3. to:xxx
  4. content_type:xxx
  5. content_length:xxx

  6. XXXXXXXXXXXXXXXXXXXXXXX
  7. XXXXXXXXXXXXXXXXXXXXXXX
  8. xxxxxxxxxxxxxxxxxxxxxxxxxx
  9. -------------#
复制代码


其中-------------#表示包结束.现在难点是不知道包的具体长度,因为tcp为流式的,我现在的做法是在recv的时候加上msg_peek的标志(收消息,但是消息还是在
socket buffer中),取出固定个字节,然后分析buffer,得到包的具体长度,然后真正的recv出来.这样做的问题是如果我收到半个包,先不做处理而是等到一个完整的包后
去取.因为对半个包不做处理,select会一直有信号表示有事件发生而频繁的调用函数处理.
请问大家对这种情况该如何处理?
谢谢!

论坛徽章:
0
2 [报告]
发表于 2007-11-22 17:55 |只看该作者
content_length不是内容的长度吗?

论坛徽章:
0
3 [报告]
发表于 2007-11-22 17:59 |只看该作者
是具体的长度,但是包头的长度是可变的.也就是说content_length在包中的位置是不确定的.

论坛徽章:
0
4 [报告]
发表于 2007-11-22 18:46 |只看该作者
为什么不先把header收完呢? 比如说收到\r\n\r\n(类似http协议)
这时候肯定有content_length了, 再感觉content_length决定要收后面的多少数据

论坛徽章:
0
5 [报告]
发表于 2007-11-22 18:49 |只看该作者
先收1K,看看有content_length不(1k的header够了吧),不行再收1K。。不可能有超过10K的header吧。。。。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2007-11-22 21:54 |只看该作者
协议是谁定的,如果定的让人搞不懂,那就先拖出来打一顿

论坛徽章:
0
7 [报告]
发表于 2007-11-22 22:13 |只看该作者
如果每1k一收,那么存在一种问题,因为包分为2种,请求和应答(只有header,较小).所以有可能收到1.x个包和半个包的情况,如果对那0.x个包做缓存将会变的很复杂,因为不止一个socket接收处理数据.理想的情况是每次取出一个包.

论坛徽章:
0
8 [报告]
发表于 2007-11-23 08:49 |只看该作者
原帖由 yuangong 于 2007-11-22 22:13 发表
如果每1k一收,那么存在一种问题,因为包分为2种,请求和应答(只有header,较小).所以有可能收到1.x个包和半个包的情况,如果对那0.x个包做缓存将会变的很复杂,因为不止一个socket接收处理数据.理想的情况是每次取出 ...

  大哥 recv 收到一个包就会返回的,只是要你吧缓冲区设1K而已

[ 本帖最后由 anthony1983 于 2007-11-23 08:53 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2007-11-23 09:03 |只看该作者
原帖由 anthony1983 于 2007-11-23 08:49 发表

  大哥 recv 收到一个包就会返回的,只是要你吧缓冲区设1K而已

这样还是有个问题:缓冲区设置多大为好,因为请求包和应答包的大小差别很大.可能请求为2k,响应只有20字节.你若1k1收,可能会收到1个或多个响应和半个请求包.

论坛徽章:
0
10 [报告]
发表于 2007-11-23 09:18 |只看该作者
recv如下情况会返回
1. 收到一个完整数据包
2.到达缓存区(包未完整)
3.出错

这样就能保证recv出来的,是一个完整的包,或者不完整,绝对不可能出现多个包!

缓存区的设置是一个为了提高效率,减少recv系统调用的方法,(你大可以10个字节的recv,然后校验content-length,但是这样会调用recv很多次!)

以前写过这样的协议,所以这方面有一点点经验。

关于请求:  1K是一个经验值, 因为大概header不会超过1K,这样通过解析header中length的长度,进一步recv(这个时候可能需要while recv),直到整个请求包收完。

关于应答: 1K也是一个经验值,应答整个包一般都不会超过1K

你可以根据你的协议需要,设这样的经验值
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP