自定义的http协议,怎样读取body?

bsnry 2014-12-22 06:13:10
head+ body都是自己封装的。

请问,我如何知道head读取完毕?

我目前的本办法是,每次读取一个字节, 读取到换行符号,就认为head读取完毕。
...全文
588 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
bsnry 2015-01-04
  • 打赏
  • 举报
回复
引用 20 楼 zhuyf87 的回复:
[quote=引用 19 楼 baidu_24733621 的回复:] [quote=引用 17 楼 zhuyf87 的回复:] [quote=引用 14 楼 baidu_24733621 的回复:] [quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。 [/quote] 当然是不固定的,这有什么关系吗[/quote] 既然不固定,。那么只有一个办法读取头, 一个个字节recv。 但是这样效率很低。 [/quote] 呃,为什么要一个一个字节的recv呢?一个线程负责将协议数据读取到一个缓冲队列中,另一个线程将缓冲队列中的数据copy出来,遍历解析,正确解析一包之后,就从缓冲队列中删除一包数据。[/quote] 以前说了, 头的大小不固定,你怎么知道, 几个字节是一个完整的头呢? 请认真看问题。 我不知道其他开源库是怎么处理的? 标准http 的头,确实是不固定的, [/quote] 不是头有多大,就必须一次recv多大。而是只要有数据就读到buffer里,然后处理线程从buffer中取数据解析。 读到特殊标记,比如\r\n\r\n时,则读完了一个完整的Head。 我认真看问题了,其实我和7楼的想法是一样的,我觉得你认为的: “既然不固定。那么只有一个办法读取头, 一个个字节recv。” 是不对的。 [/quote] 赞同 接受线程,每次接受几k大小的包,然后放到buffer中,接受线程只管接受,不关协议内容。 处理线程去处理包里的东西。 谢谢
baidu_24733621 2014-12-25
  • 打赏
  • 举报
回复
引用 17 楼 zhuyf87 的回复:
[quote=引用 14 楼 baidu_24733621 的回复:] [quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。 [/quote] 当然是不固定的,这有什么关系吗[/quote] 既然不固定,。那么只有一个办法读取头, 一个个字节recv。 但是这样效率很低。 [/quote] 呃,为什么要一个一个字节的recv呢?一个线程负责将协议数据读取到一个缓冲队列中,另一个线程将缓冲队列中的数据copy出来,遍历解析,正确解析一包之后,就从缓冲队列中删除一包数据。[/quote] 以前说了, 头的大小不固定,你怎么知道, 几个字节是一个完整的头呢? 请认真看问题。 我不知道其他开源库是怎么处理的? 标准http 的头,确实是不固定的,
xionggch 2014-12-25
  • 打赏
  • 举报
回复
根据自己项目需求,采用相应的方法,没有那种方法绝对的适合所有应用
zhuyf87 2014-12-25
  • 打赏
  • 举报
回复
引用 14 楼 baidu_24733621 的回复:
[quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。 [/quote] 当然是不固定的,这有什么关系吗[/quote] 既然不固定,。那么只有一个办法读取头, 一个个字节recv。 但是这样效率很低。 [/quote] 呃,为什么要一个一个字节的recv呢?一个线程负责将协议数据读取到一个缓冲队列中,另一个线程将缓冲队列中的数据copy出来,遍历解析,正确解析一包之后,就从缓冲队列中删除一包数据。
zhuyf87 2014-12-25
  • 打赏
  • 举报
回复
引用 19 楼 baidu_24733621 的回复:
[quote=引用 17 楼 zhuyf87 的回复:] [quote=引用 14 楼 baidu_24733621 的回复:] [quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。 [/quote] 当然是不固定的,这有什么关系吗[/quote] 既然不固定,。那么只有一个办法读取头, 一个个字节recv。 但是这样效率很低。 [/quote] 呃,为什么要一个一个字节的recv呢?一个线程负责将协议数据读取到一个缓冲队列中,另一个线程将缓冲队列中的数据copy出来,遍历解析,正确解析一包之后,就从缓冲队列中删除一包数据。[/quote] 以前说了, 头的大小不固定,你怎么知道, 几个字节是一个完整的头呢? 请认真看问题。 我不知道其他开源库是怎么处理的? 标准http 的头,确实是不固定的, [/quote] 不是头有多大,就必须一次recv多大。而是只要有数据就读到buffer里,然后处理线程从buffer中取数据解析。 读到特殊标记,比如\r\n\r\n时,则读完了一个完整的Head。 我认真看问题了,其实我和7楼的想法是一样的,我觉得你认为的: “既然不固定。那么只有一个办法读取头, 一个个字节recv。” 是不对的。
赵4老师 2014-12-24
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
赵4老师 2014-12-24
  • 打赏
  • 举报
回复
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
baidu_24733621 2014-12-24
  • 打赏
  • 举报
回复
引用 13 楼 zhuyf87 的回复:
[quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。 [/quote] 当然是不固定的,这有什么关系吗[/quote] 既然不固定,。那么只有一个办法读取头, 一个个字节recv。 但是这样效率很低。
zhuyf87 2014-12-23
  • 打赏
  • 举报
回复
加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
starytx 2014-12-23
  • 打赏
  • 举报
回复
引用 2 楼 u012879787 的回复:
[quote=引用 1 楼 starytx 的回复:] 固定长度不行吗?或者说协议设置成前四个字节保存head的长度,先读取到这个信息,然后根据这个读取对应长度的信息
开源库是如何处理的? 自定义http协议,感觉头+体里的东西都是按照标准http协议走的, 标准 http的头里没有头大小这个东西。 你的方法不对吧 [/quote]我没研究过http协议,只是针对lz说的“自定义”来说可以这样,如果要和标准依附那就要遵循标准,而不是自定义了
zhuyf87 2014-12-23
  • 打赏
  • 举报
回复
要么加len字段,要么加标记。
luciferisnotsatan 2014-12-23
  • 打赏
  • 举报
回复
引用 6 楼 bsnry 的回复:
[quote=引用 5 楼 luciferisnotsatan 的回复:] [quote=引用 2 楼 u012879787 的回复:] [quote=引用 1 楼 starytx 的回复:] 固定长度不行吗?或者说协议设置成前四个字节保存head的长度,先读取到这个信息,然后根据这个读取对应长度的信息
开源库是如何处理的? 自定义http协议,感觉头+体里的东西都是按照标准http协议走的, 标准 http的头里没有头大小这个东西。 你的方法不对吧 [/quote] 标准http头是以两个连续的“\r\n”结尾的。 如果你不按标准,要自己定义一套,那么就要你自己想怎么算结束了[/quote] 两个\r\n, 那么如何读取head, 每次读取一个字符来判断头是否结束,不觉得效率太低了吗 [/quote] 你不会socket一次接收一大段数据到内存buffer里,然后再去判断这段buffer里有没有连续的\r\n。干嘛要一个字节一个字节recv 同时,CPU解析这么段http文本的所需时间相对于网络传输的时间来说可以忽略不计的。
bsnry 2014-12-23
  • 打赏
  • 举报
回复
引用 5 楼 luciferisnotsatan 的回复:
[quote=引用 2 楼 u012879787 的回复:] [quote=引用 1 楼 starytx 的回复:] 固定长度不行吗?或者说协议设置成前四个字节保存head的长度,先读取到这个信息,然后根据这个读取对应长度的信息
开源库是如何处理的? 自定义http协议,感觉头+体里的东西都是按照标准http协议走的, 标准 http的头里没有头大小这个东西。 你的方法不对吧 [/quote] 标准http头是以两个连续的“\r\n”结尾的。 如果你不按标准,要自己定义一套,那么就要你自己想怎么算结束了[/quote] 两个\r\n, 那么如何读取head, 每次读取一个字符来判断头是否结束,不觉得效率太低了吗
luciferisnotsatan 2014-12-23
  • 打赏
  • 举报
回复
引用 2 楼 u012879787 的回复:
[quote=引用 1 楼 starytx 的回复:] 固定长度不行吗?或者说协议设置成前四个字节保存head的长度,先读取到这个信息,然后根据这个读取对应长度的信息
开源库是如何处理的? 自定义http协议,感觉头+体里的东西都是按照标准http协议走的, 标准 http的头里没有头大小这个东西。 你的方法不对吧 [/quote] 标准http头是以两个连续的“\r\n”结尾的。 如果你不按标准,要自己定义一套,那么就要你自己想怎么算结束了
zhuyf87 2014-12-23
  • 打赏
  • 举报
回复
引用 11 楼 baidu_24733621 的回复:
[quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。 [/quote] 当然是不固定的,这有什么关系吗
layershow 2014-12-23
  • 打赏
  • 举报
回复
协议栈一般是这么实现(大概思路): 1. 查找两个 "\r\n" 以确定头结束 2. 因为是 TCP,没找到则需要缓存数据等待后续数据到达(新数据到达开始 1) 3. 找到了就知道 Header 在哪里结束,对 Header 部分查找 "\r\n"(处理每一行) 4. 对每一行数据查找 ":" 分割,前面的部分匹配头域关键字,按照不同的头来处理 ":" 之后的内容 5. 获得 Content-Length 头,检查 Body 的数据是否已收全(Header 结束的位置至数据的尾部) 6. 如果没有收全,需要等待 Body 的后续数据,因此缓存已处理内容(新数据到达开始 5) 7. 按照 Body 的类型,解析 Body 8. 仍有剩余数据(已收取数据减去 Header 和 Body 的长度)需要开始下一个报文的解析(因为是 TCP),继续 1
baidu_24733621 2014-12-23
  • 打赏
  • 举报
回复
引用 10 楼 zhuyf87 的回复:
加标记不会降低效率,本来http头里面的各个字段也需要遍历一遍才能解析出来。
标准http的头的大小不固定。
zuxi 2014-12-22
  • 打赏
  • 举报
回复
请参考nginx的HTTP协议解码部分。
老许要老婆么 2014-12-22
  • 打赏
  • 举报
回复
加一个 字段标注 head多大
苦逼码农 2014-12-22
  • 打赏
  • 举报
回复
引用 1 楼 starytx 的回复:
固定长度不行吗?或者说协议设置成前四个字节保存head的长度,先读取到这个信息,然后根据这个读取对应长度的信息
开源库是如何处理的? 自定义http协议,感觉头+体里的东西都是按照标准http协议走的, 标准 http的头里没有头大小这个东西。 你的方法不对吧
加载更多回复(1)

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧