【问题标题】:Python dectect the length of the data with socketPython用socket检测数据的长度
【发布时间】:2015-02-12 16:16:57
【问题描述】:

我找到了这段代码来检测帧中加密数据的长度:

header = self.request.recv(5)
if header == '':
   #print 'client disconnected'
   running = False
   break
(content_type, version, length) = struct.unpack('>BHH', header)
data = self.request.recv(length)

来源:

这段代码,监听客户端和服务器之间的连接。当客户端与服务器通信时,self.request.recv(5) 可以获得帧中标题的长度。然后我们使用这个长度来获取数据。

如果我们打印客户端和服务器之间的交换:

Client  --> [proxy] -----> Server
length : 24 #why 24 ?
Client  --> [proxy] -----> Server
length: 80 #length of the data
Client  <-- [proxy] <----- Server

我们可以看到客户端会向服务器发送两个数据包。 如果我改变了

data = self.request.recv(length)

data = self.request.recv(4096)

只进行一次交换。

Client  --> [proxy] -----> Server
length: 109 #length of the data + the header
Client  <-- [proxy] <----- Server

我的问题是为什么我们只需要 5 的大小来获取长度、内容类型信息?有没有可以理解的文档?

为什么有两个请求:一个是 24,另一个是我们数据的长度?

【问题讨论】:

    标签: python sockets python-2.7 unpack


    【解决方案1】:

    为什么我们只需要大小为 5 就可以得到长度,content_type 信息?

    因为显然这就是协议的设计方式。

    二进制流只保证当一些字节被放入流的一端时,它们以相同的顺序到达流的另一端。对于通过二进制流传输消息,明显的问题是:消息边界在哪里?这个问题的经典解决方案是为消息添加前缀,即所谓的标头。此标头具有固定大小,通信伙伴都知道。这样,收件人就可以安全地阅读 header、message、header、message(我猜你掌握了这个概念,这是一种交替的方式)。如您所见,标头不包含消息数据——它只是通信“开销”。这个开销应该保持很小。存储此类信息的最有效(空间方面)方式是二进制形式,使用某种代码,再次,通信双方都必须知道该代码。确实,5个字节的信息量也不少。

    '>BHH' 格式字符串表示这个 5 字节的头是这样构建的:

    1. 无符号字符(1 字节)
    2. 无符号短(2 字节)
    3. 无符号短(2 字节)

    有足够的空间来存储长度和内容类型等信息,您不觉得吗?此标头可以编码 256 种不同的内容类型、65536 种不同的版本,以及 0 到 65535 字节之间的消息长度。

    为什么有两个请求:一个是 24,另一个是长度为 我们的数据?

    如果您的网络取证/流量分析与您从代码中推断出的不相符,则这两种分析中的一种是错误的/不完整的。在这种情况下,我猜你的流量分析是正确的,但是你还没有理解这种通信的所有相关代码。请注意,我没有查看您链接到的源代码。

    【讨论】:

    • 有没有什么地方可以找到关于 5 个字节的信息?
    • 当然。继续阅读有关 TLS 的内容,您将在某些时候理解这些协议概念和相应的问题(最终导致 Heartbleed、Poodle 等)。我想说的是:您想要做什么要求您了解这 5 个字节在您的主题(TLS/SSL 及其漏洞)的上下文中是什么。在那里做你自己的研究,这将是鼓舞人心的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2015-12-21
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    相关资源
    最近更新 更多