用struct模块实现python socket收发自定义TCP包

最近跳槽到西安一家机器人公司,我们的产品属于教育机器人的范畴,为了增强客户吸引力,引进了一个智能家居公司的产品API接口,让机器人来操作智能家居

该公司的智能家居API是自定义TCP包,即直接在TCP头后面写自定义数据结构:

客户端请求下载 家具数据库 的格式

命令字(4字节,小端)

0x4c

服务器返回请求结果 的格式

命令字(4字节,小端) payload长度(4字节,小端) payload(N*1字节)
0x43 11262(尺寸很大) sqlite数据库

默认python socket只能收发字符串,需要借助struct才能收发二进制数据

发送请求

cmd_word = 0x4c
tx_buf = struct.pack('<I', cmd_word)
sock.sendall(tx_buf)

tx_buf据struct的文档说是其对输入编码生成的字符串,用type(tx_buf)显示确实是<type ‘str‘>,print tx_buf显示字母L

但len(tx_buf) == 4, print repr(tx_buf)显示

‘L\x00\x00\x00‘

也就是说len(‘L\x00\x00\x00‘) == 4

对于从C语言转过来的人来说,上面情况真是理解不能,但它就是发送成功了

接收应答

fp = open('house.db', 'wb+')
recv_cnt = 0
while True:
    rx_buf = sock.recv(4096)
    len_buf = len(rx_buf)
    if len_buf ==0:
        break
    if recv_cnt == 0:
        cmd_word, data_len_total = struct.unpack(rx_buf[0:8])
        buf = buffer(rx_buf, 8, len_buf - 8)
        fp.write(buf)
    else:
        buf = buffer(rx_buf)
        fp.write(buf)
    recv_cnt = recv_cnt +1

注意:

0、接收自定义帧头时用unpack,可以获得结构体各字段取值

1、接收自定义帧内容(字节流)时不用unpack,因为unpack返回的是tuple,而write不支持tuple类型

2、因为是二进制写入,所以必须将str转成buffer类型

3、二进制数据很大时,底层会拆分成多个以太网帧,如果你sendall后马上recv,则可能只收到1448字节,不要担心,这是因为你recv时内核协议栈只有一帧这么多数据,它全部返回给你了,满足socket编程的标准



时间: 2024-11-14 12:37:03

用struct模块实现python socket收发自定义TCP包的相关文章

python/socket编程之粘包

python/socket编程之粘包 粘包: 只有TCP有尿包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提取数据,当然也有可能是3k或者多k提取数据,也就是说,应用程序是不可见的,因此TCP协议是面来那个流的协议,这也是容易出现粘包的原因而UDP是面向笑死的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任一字节的数据,这一点和TCP是很同的.怎样定义消息呢?认为对方一次

python socket编程 ,tcp,udp服务端客户端创建

转自http://blog.csdn.net/rebelqsp/article/details/22109925 Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发. 下面讲的是Socket模块功能 1.Socket 类型 套接字格式: socket(family,type[,protocal]) 使用给定的地址族.套接字类型.协议编号

Python—socket编程和黏包问题

TCP协议与UDP协议 TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务.收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制. 即面向流的通信是无消息保护边界的. UDP(user datagram protoc

黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载

黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数据会直接丢失,俗称丢包) #面试 #首先只有在TCP协议中才有黏包现象,是因为TCP协议是面向流的协议, #在发送的数据传输的过程中还有缓存机制来避免数据丢失 #因此在连续发送小数据的时候,以及接收大小不符的时候,都容易产生黏包现象 #本质是不知道客户端发送的数据长度 面试中解释黏包 #连续send

[Python_7] Python Socket 编程

0. 说明 Python Socket 编程 1. TCP 协议 [TCP Server] 通过 netstat -ano 查看端口是否开启 # -*-coding:utf-8-*- """ TCP 协议的 Socket 编程,Server 端 Server 端绑定到指定地址,监听特定的端口,接受发来的连接请求 """ import threading import socket import time class CommThread(thre

python中struct模块

转:  http://www.cnblogs.com/coser/archive/2011/12/17/2291160.html 最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结. 了解c语言的人,一定会知道struct结构体在c语言中的作用,它定义了一种结构,里面包含不同类型的数据(int,char,bool等等),方便对 某一结构对象进行处理.而在网络通信

python struct模块

一.简介 了解c语言的人,一定会知道struct结构体在c语言中的作用,它定义了一种结构,里面包含不同类型的数据(int, char, bool等等),方便对某一结构对象进行处理.而在网络通信当中,大多传递的数据是以二进制流(binary data)存在的.当传递字符串时,不必担心太多的问题,而当传递诸如int.char之类的基本数据的时候,就需要有一种机制将某些特定的结构体类型打包成二进制流的字符串然后再网络传输,而接收端也应该可以通过某种机制进行解包还原出原始的结构体数据.python中的s

python中struct模块及packet和unpacket

转自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html 我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组,字典.但是C语言中有些字节型的变量,在python中该如何实现呢?这点颇为重要,特别是要在网络上进行数据传输的话. 有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体. st

浅析Python中的struct模块

最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结. 了解c语言的人,一定会知道struct结构体在c语言中的作用,它定义了一种结构,里面包含不同类型的数据(int,char,bool等等),方便对某一结构对象进行处理.而在网络通信当中,大多传递的数据是以二进制流(binary data)存在的.当传递字符串时,不必担心太多的问题,而当传递诸如int.char之