有关 tcp 和 http 的问题

2017-12-01 13:20:45 +08:00
 drzhaug

我在思考一个问题,希望各位能给我解答下。 有没有可能一个 http 的 response 数据过长,超过了单个 tcp 的 payload,然后被分割在多个 tcp 报文中? 如果是这样的话,假设被分割到两个 tcp 报文当中了,如何识别第二个报文的 payload 是 http 数据?(因为可能无法通过 HTTP / 1.1 识别了)

5537 次点击
所在节点    程序员
45 条回复
drzhaug
2017-12-01 14:15:44 +08:00
@zhangysh1995 你没理解我说的意思 你说的东西太简单了
drzhaug
2017-12-01 14:18:07 +08:00
@xiaxiaocao 谢谢,我刚刚没有太理解你的代码,我又看了一下,应该是我要的东西,我是想在 http 的基础上把图片截取出来。ps:我才知道 pcap 有 go 版本的,果断准备放弃 c 了。
zhangysh1995
2017-12-01 14:20:43 +08:00
@zhangysh1995 因为 IP 分段之后,到大主机会重新打包的。头部有 checksum 或者 length 这种参数,底层就处理了。不管里面存的是什么,是要长度不够就会拼起来。具体实现你要去看协议栈了,因为 HTTP 不管这些事情,它只管丢给传输层。建议重新看下计算机网络。
clino
2017-12-01 14:25:40 +08:00
@drzhaug #9 你标题的问题说和 tcp 相关,然后你这里问的问题又变成和 tcp 无关
clino
2017-12-01 14:27:46 +08:00
建议楼主用 wireshark 抓个包然后看看协议分析以后的数据,估计能比较明了,ip/tcp/http 这几个层级的数据解析都能看到
drzhaug
2017-12-01 14:30:13 +08:00
@zhangysh1995 好吧,我确实应该再看一下。但你能不能先告我一下我应该怎么做:我捕获的流过路由器上的 ethernet 帧,因该怎么处理才能获得完整的 http 响应数据的 body ?大概说一下就行,能理解的。谢谢
easing
2017-12-01 14:33:29 +08:00
用你问题里的例子,单纯看第二个 tcp 包是看不出来是不是 http payload 的,因为可能没有 http response header 字段供你判断,对 TCP 来说,它感知不了也不应该感知这是什么,那如何判断呢?只能在上层即 http 里,因为之前接收到了 response header,且有 content-length 信息,就会等待这么长的数据传上来,不管等多少个包,只要等够这么长了, 就算这个 http response 结束。
hcnhcn012
2017-12-01 14:39:17 +08:00
这个你不用担心,tcp 中的 ack 和 seq 字段一定会保证 tcp 数据段的有序的,超过了 MSS 就会拆包,不管里面包着的 http 怎么样,所以说这是面向 stream,而且 tcp 数据段不像 ip 数据包一样里面有个协议字段,也就是说 tcp 从来不知道数据部分封装的是个什么东西,也就是说在 tcp 层面无法识别 http
zhangysh1995
2017-12-01 14:45:08 +08:00
@drzhaug 我们一般的操作都是在自己的主机上进行的,用 Wireshark 可以完成,它也支持交换机或者路由器,可以参考这里 https://wiki.wireshark.org/CaptureSetup/Ethernet (全英文)。不过我觉得应该有更好的解决方案,这个就超出我的知识范围了,不好意思。
xiaxiaocao
2017-12-01 14:49:09 +08:00
@drzhaug 你这么说就明白多了,和我那个项目应该是同样功能。
主要是把 tcp 连接上的包重新组织好,然后就可以当作两个流来处理了,是不是 http 就通过开头的的内容可以判断。一个 http 内容读完之后如果下面的不是新的合法的 http 的 header 就放弃,当然这种情况基本不会出现。
wcsjtu
2017-12-01 14:57:01 +08:00
@drzhaug 你这是要自己实现个 tcp/ip 协议栈啊
gejigeji
2017-12-01 15:00:53 +08:00
所以应届生校招经常问七层网络协议的问题
neoblackcap
2017-12-01 15:07:36 +08:00
你就是要自己进行抓包对吧,在不用 libpcap 的情况下,那么说到底就是自己在用户空间重新实现 tcp/ip 协议栈,你具体可以参考 https://github.com/F-Stack/f-stack。
等你完成这个之后你就得到了一个你自己实现的 stock api,剩下的就是一般 http parser 的问题了,反正你得到了完整的 tcp 流了
Chingim
2017-12-01 16:07:16 +08:00
tcp 根本就不关心你 payload 不 payload。应用层给他什么他就传什么,如果包太大,它就拆了再传,到了目的地再把拆的包封好然后发给应用层。
如果你想了解如何拆装,那看 tcp 就好。
iceheart
2017-12-01 19:09:30 +08:00
看上去干的不是什么好事
cwek
2017-12-01 21:26:35 +08:00
TCP 会自动帮你拼合成连续的字节流送上应用层的,应用层感知不到。
drzhaug
2017-12-02 00:38:27 +08:00
@iceheart 哈哈哈,就你精,我学安全的。。。
luxin88
2017-12-02 00:55:35 +08:00
@cabing 对于单个请求来讲,应该不会涉及到粘包的问题,只有连续发送,才要考虑粘包
dangyuluo
2017-12-02 01:11:46 +08:00
楼上说的很明白了,tcp 不管你的应用,你传多长的都行。他会根据自己的协议进行分包、合并、请求重发等。
sinxccc
2017-12-02 02:21:58 +08:00
@gejigeji 不管应届社招,不管什么级别,问问从浏览器里敲进去网址到整个网页显示完这段时间发生了什么总没错的ˊ_>ˋ

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/411096

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX