Python socket 通信如何分包

2017-04-01 21:48:37 +08:00
 just1

比如服务端发送 00 01 ; 00 02 两个包 客户端用 python socket.recv()的函数会接收到 00 01 00 02 (粘连在一起) 如何分包? 服务端我无法控制。 客户端用 python3

之前发在 segmentfault 没人理。。。 https://segmentfault.com/q/1010000008888222

6217 次点击
所在节点    Python
31 条回复
wevsty
2017-04-01 22:01:44 +08:00
发一个,等几秒再发第二个
zyEros
2017-04-01 22:01:49 +08:00
尾部特殊字符,或者头部用 2 字节表明 body 的长度
just1
2017-04-01 22:02:30 +08:00
@wevsty
@zyEros 服务端不可控
wevsty
2017-04-01 22:04:39 +08:00
@just1 那就自己按照包大小或者包格式分割一下,如果没有固定格式,弃坑吧
zyEros
2017-04-01 22:05:29 +08:00
@just1 服务端都不能标明你 body 的长度或者截止位置,你能怎么办,没办法
dant
2017-04-01 22:16:48 +08:00
TCP 是数据流。
just1
2017-04-01 22:18:49 +08:00
@zyEros
@wevsty
@dant TAT 那 wireshark 怎么实现分包的
maemual
2017-04-01 22:24:21 +08:00
tcp 流式数据你是分不了包的。只能加结束符或者发送 content length 之类的东西来判断。
ifaii
2017-04-01 22:41:50 +08:00
tcp 是流,这种需求不如试试 udp
lvxudong
2017-04-01 22:49:43 +08:00
socket.recv(num) 可以指定接收字节数
wevsty
2017-04-01 23:06:57 +08:00
@just1 抓包工具抓的并不只是 tcp 层面的数据。一个 tcp 包除了发送或者接收的数据还包括了很多内容,比如目标端口,原端口,也有些包不包含应用层的数据。和你理解的接收包不是一回事。解释起来很复杂,但是在应用层的层面上 TCP 应用层的应用是分不清楚包的。如果一定要按照包来处理内容,请使用 UDP 。
当然,使用 UDP 你肯定会遇到更多麻烦。
mooncakejs
2017-04-01 23:17:20 +08:00
tcp 不需要分包。按照应用层协议解析就好
jimzhong
2017-04-01 23:18:32 +08:00
如果你是 Linux 的 UNIX Socket ,可以试试 SEQPACKET 协议。
如果是 TCP ,那么建议自己设计一个头,里面包含数据长度,就像 HTTP 的 Content-length 一样
jimzhong
2017-04-01 23:20:21 +08:00
@just1 TCP 在传递到 IP 层的时候会分成一个个 Segment , Segment 的大小由 MSS 决定。每个 Segment 被封装到一个 IP 包里面。但是 Segment 对于应用程序是不可见的,应用程序看到的就是流。
just1
2017-04-01 23:25:36 +08:00
@maemual
@ifaii
@lvxudong
@mooncakejs (´・_・`)模拟某个客户端的啦,我再想办法找找他的处理模式

@wevsty @jimzhong 。◕‿◕。感谢解惑
raiz
2017-04-01 23:26:42 +08:00
既然是tcp,本身是流,肯定要有数据协议,就是根据数据包格式,起始标识符,长度域或结束符来判断完整的一包.具体就是逐字节的读取,判断,直到一完整包,给上层,继续读取判断.
pright
2017-04-02 00:50:50 +08:00
如果每个包长度都小于 MSS ,你也可以用 raw socket 自己收 233
best1a
2017-04-02 01:40:28 +08:00
@pright 即使每个包长度都小于 MSS ,如果服务端开启了 nagle ,一样会有这问题吧
NoAnyLove
2017-04-02 04:26:18 +08:00
TCP 是面向数据流的啊,你可以自己定义一个应用层的格式,比如每个包头包含这个包的大小。 recv 的时候先接收包头大小的内容,然后再根据包头接受剩下的数据。当你用直接用 TCP 协议的时候,就不用考虑下面的分包问题了。除非你想用 UDP
ryd994
2017-04-02 07:39:42 +08:00
1.每个包以长度开头
2.用库或者自己再实现一层 buffer ,用 deque 实现不难的
3.SCTP

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

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

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

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

© 2021 V2EX