python通过TCP套接字发送/接收十六进制数据

问题描述:

我有一个ethenet访问控制设备,据说可以通过TCP进行通信。
我怎样才能通过输入十六进制数据发送pachet,因为这是我从他们的手工有(标准格式发送,每个命令后收到的通信数据包)
能否请你展示一些示例代码或链接上手....

python通过TCP套接字发送/接收十六进制数据

 
standard return packet from the terminal 
           Size (bytes) 
BS (0x08) : ASCII Character   1 
STX (0x02) : ASCII Character  1 
LENGTH : length from BS to ETX  4 
TID : system unique I.D.   1 
RESULT        1 
DATA : returned parameter   N 
CHECKSUM : byte sum from BS to DATA 1 
ETX (0x03) : ASCII Character  1 
 
Standard command packet to the terminal 
           Size (bytes) 
ACK (0x06) : ASCII Character   1 
STX (0x02) : ASCII Character   1 
LENGTH : length from ACK to ETX  4 
TID : system unique I.D. (ex: 1)  1 
COMMAND        1 
Access Key(Optional)     6 
DATA : command parameter    N 
CHECKSUM : byte sum from ACK to DATA 1 
ETX (0x03) : ASCII Character   1 

This packet starts from ACK. 
In this packet, multiple byte value must be started from MSB. 
For example, if length was 10, LENGTH is 0x00 0x00 0x00 0x0a. 
+0

,当我得到s.send发送的数据,我从s.recv,如何应对我可以使用“打印”显示以十六进制显示的内容吗? – Mike 2010-03-14 16:22:29

+0

您使用'struct.unpack'(用于响应数据包的8字节开始) - 再次确保您获得整个响应是关键,因为TCP是流协议,而不是数据报协议,因此可能会任意截断东西 - 不太可能,但为什么冒险呢?就像你应该使用'sendall'而不是'send'来确保整个包装被传输一样,正如我在回复你对我的答案的评论中所提到的那样。 – 2010-03-14 17:23:01

我想用struct.pack来准备要发送的数据字节串。请务必使用>开始打包格式,这意味着您需要big-endian订购和标准尺寸,因为它们记录得非常清楚!所以(我不知道访问密钥的“可选”意味着什么,我假设它意味着如果你没有访问密钥,该字段可以是全零字节),如果“数据”是已经是一个字节的字符串,并“命令”,例如一个小的无符号整数,像...:

def stringfor(command, data, accesskey='\0'*6, tid=1): 
    length = 16 + len(data) 
    prefix = struct.pack('>BBIBB6s', 6, 2, length, tid, command, accesskey) 
    checksum = sum(ord(c) for c in prefix) &0xFF 
    return prefix + chr(checksum) + chr(3) 
+0

很好:)谢谢。 然后用s.send发送这个? – Mike 2010-03-14 16:18:10

+0

@Mike,当然还是's.sendall'(可能会更好,因为你希望100%确定所有的数据包都被发送 - 但是,然后你的连接的MTU可能足够大,这没有什么区别),请参阅http ://docs.python.org/library/socket.html?highlight = socket.send#socket.socket.sendall。 – 2010-03-14 17:20:01

只是编码字符串中的十六进制数据:

'\x34\x82\xf6' 
+0

,如果十六进制数据没有ASCII等价物,这是一个问题吗? – Mike 2010-03-14 16:05:08

+1

您代表的是原始字节。 'str'不关心它是否是ASCII;只有像'print'这样的东西可以。 – 2010-03-14 16:13:56