深交所新版行情二进制数据接收分析

  • 2017-03-19 17:17:05
  • 529
  • 0

这里主要通过以2015年做过的一个项目:深交所行情的二进制数据接收以及分析为例来介绍python struct模块和socket模块的使用。

先上最后一位验证码的计算方法:

def checksum(pack_content):
"""
pack_content为本次要发送的二进制内容
""" cks = 0 for i in pack_content: a = struct.unpack('!B',i) cks += a[0] return cks%256

 

一、Struct模块

前面已讲过,了解python模块有两大神技:help与dir方法,通过help可以查看大概定义以及用法, 通过dir可以了解属性以及方法。

首先使用help方法了解定义及其大致用法:help(struct)

DESCRIPTION
    Functions to convert between Python values and C structs represented
    as Python strings. It uses format strings (explained below) as compact
    descriptions of the lay-out of the C structs and the intended conversion
    to/from Python values.

    The optional first format char indicates byte order, size and alignment:
      @: native order, size & alignment (default)
      =: native order, std. size & alignment
      <: little-endian, std. size & alignment
      >: big-endian, std. size & alignment
      !: same as >

    The remaining chars indicate types of args and must match exactly;
    these can be preceded by a decimal repeat count:
      x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;
      ?: _Bool (requires C99; if not available, char is used instead)
      h:short; H:unsigned short; i:int; I:unsigned int;
      l:long; L:unsigned long; f:float; d:double.
    Special cases (preceding decimal count indicates length):
      s:string (array of char); p: pascal string (with count byte).
    Special case (only available in native format):
      P:an integer type that is wide enough to hold a pointer.
    Special case (not in native mode unless 'long long' in platform C):
      q:long long; Q:unsigned long long
    Whitespace between formats is ignored.

    The variable struct.error is an exception raised on errors.

 

解释:用来做python数据与C 结构代表的python字符(一般为通过python socket模块接收二进制数据流后的字符形式)数据之间转换的函数集。它用指定格式的字符串来描述二进制数据流,并且通过这种指定格式的字符串来实现python数据与二进制数据流二者之间的转换, 字节流的顺序以及格式由这种指定格式字符串的第一个字符决定。

举例:

这里以一段二进制行情包的数据为例

import struct
raw_str = '\x00\x01\x8c\xe1\x00\x00\x00_16025380010000023102 \x00\x0101\x00G\x8e:x\xc1*\xbe        S1000001070030468786  0       12\x00\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00>\x80253800\x00\x00\x00\xe2'
format_string = '!II3s6s8s4sH2sq8s10s12s4s4s1s1sqq6s'
struct.unpack_from(format_string, raw_str, 0)
结果为:(101601, 95, '160', '253800', '10000023', '102 ', 1, '01', 20141105131629246L, ' ', 'S100000107', '0030468786 ', '0 ',', '1', '2', 200, 16000, '253800')
pack_con = (101601, 95, '160', '253800', '10000023', '102 ', 1, '01', 20141105131629246L, '        ', 'S100000107', '0030468786  ', '0   ',', '1', '2', 200, 16000, '253800')
buffer_size = struct.calcsize(format_string)
msg_pack = create_string_buffer(buffer_size) struct.pack_into(fomat_string, msg_pack, 0, *pack_con)

print msg_pack.raw

结果为:'\x00\x01\x8c\xe1\x00\x00\x00_16025380010000023102 \x00\x0101\x00G\x8e:x\xc1*\xbe        S1000001070030468786  0       12\x00\x00\

x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00>\x80253800'

从上面例子可以出通过struct可以实现C 结构代表的python字符与python数据之间的转换。

通过上面的例子, 首先最需先了解format_string的相关的语法与写法, 先看两张图:

左图是各个format char所代表的数据类型以及字节长度,右图是讲解第一个format char所代表的的含义(即接收字节流的顺序以及格式)。

 

二、socket

关于socket的介绍,网上有很多, 这里只简单的说下。

socket的本质是编程接口, 是双向通信连接以及数据交换的一端。连接方式有udp和tcp 两种。

创建socket端的代码很简单:

import socket
HOST = socket.gethostbyname(socket.gethostname()) sck = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sck.bind((HOST,PORT)) sck.listen(0)
while 1:
conn, addr = sck.accept()
binary_content = conn.recv(8)
这里接收的binary_content 就可以直接作为上述例子中raw_str变量通过struct模块进行编译了。
注:这里的接收字节的长度一般看一段报文头中的某个字段值(深交所报文的前八个字节为头部), 具体可以查看提供规则方的官方接口文档。

 

 

 

 


发表评论

* *