UDP通信——使用python通过UDP通信来发送和解析数据

UDP通信——使用python通过UDP通信来发送和解析数据

2023年7月15日发(作者:)

UDP通信——使⽤python通过UDP通信来发送和解析数据UDP通信——使⽤python通过UDP通信来发送和解析数据经常我们要发送的信息是结构化的数据,此时发送和接收数据结构就是⼀个很基本的⼯作,怎样来实现呢?发送和接收数据结构我们要⽤到 python 的 struct 模块,该模块可以⽤ struct来处理c语⾔中的结构体。⾸先来看下struct中⽀持的数据类型FormatxcbBhHiIlLqQfdspPC Typepad bytecharsigned charunsigned char_Boolshortunsigned shortintunsinged intlongunsigned longlong longunsigned long longfloatdoublechar[]char[]void *Pythonno valuestring of length 1integerintegerboolintegerintegerintegerinteger or longintegerlonglonglongfloatfloatstringstringlong字节数884811struct模块中最重要的三个函数是pack(), unpack(), calcsize()pack(fmt, v1, v2, …) 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)unpack(fmt, string) 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple(元组)calcsize(fmt) 计算给定的格式(fmt)占⽤多少字节的内存这⾥需要注意的是字节对齐的情况,字节对齐,简单来讲就是说⽐如⼀个 char 类型字符本来占1个字节,但是在结构体中,根据前后数据类型的不同,为了计算机读取内存的⽅便,会按照⼀定的规则给该 char 类型数据分配不只1个字节,可能是2个,那多出来的字节会导致我们按照各个数据类型长度算出来的与实际的不⼀样,我们可以写⼀段验证代码(下⾯是⼀段C++代码,因为⽤python来写的话还要⽤到⼀个库,下⾯会说到):#include struct A{ double num1; double num2; bool num3;};#pragma pack(push,1)struct B{ double num1; double num2; bool num3;};#pragma pack(pop)int main(){ printf("length of A: %dnlength of B: %dn", sizeof(A), sizeof(B)); return 0;}结果是:length of A: 24length of B: 171个double类型数据8个字节,1个bool类型数据1个字节,应该是17个字节,但是A的长度确实24个字节,相当于是3个double的长度,这就是字节对齐。⽽B的定义前后都加了⼀句话,#pragma pack(push,1) 作⽤:是指把原来对齐⽅式设置压栈,并设新的对齐⽅式设置为⼀个字节对齐#pragma pack(pop) 作⽤:恢复对齐状态加上这两句话,就使得结构体的内存是连续的。下⾯就可以⽤unpack()来进⾏数据解析了,要注意的是:字节对齐也有不同的规则,⽐如⼤端对齐、⼩端对齐等,所以需要struct⽤格式中的第⼀个字符来改变对齐⽅式。如下:character@=<>!byte ordernativenativelittle-endianbig-endiannetwork(= big-endian)sizenativestandardstandardstandardstandardaligenmentnativenonenonenonenone⽤法就是在unpack(fmt, string)中的 fmt 加上符号,⽐如 ’<2i3d’表⽰将数据解析为⼩端对齐⽅式的2个int类型和3个double类型。⼀、使⽤unpack()⽅式解析数据发送端是c++代码,接收端是python。发送端#include #include #include #include #include #define PORT 8000#pragma pack(push,1)

struct B //要发送的数据结构{ double num1; double num2; bool num3;};#pragma pack(pop)int main(void){ //实例化结构体,并赋值 B message;

1=1200; 2=3000; 3=1; //定义socket套字 int sock; struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); //把servaddr内存清零 sock = socket(AF_INET, SOCK_DGRAM, 0); _family = AF_INET; _port = htons(PORT); _addr.s_addr = inet_addr("192.168.43.131"); while (1)

{ printf("向服务器发送:%.f, %.f, %dn",1,2,3); sendto(sock, &message, sizeof(B), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); sleep(1); } close(sock); return 0;}接收端# -*- coding: utf-8 -*-import socketimport timeimport structPORT = 8000receiver_socket = (_INET, _DGRAM)address = ("192.168.43.131", PORT)receiver_(address)while True: now = () print(me('%Y-%m-%d %H:%M:%S',ime(now))) receive_message, client = receiver_om(1024) data = ('<2d1b',receive_message) print 'num1:' ,data[0], ' num2:',data[1], ' num3:',data[2]结果如图:⼆、使⽤memmove操作内存解析数据思路就是接收端定义⼀个与发送端相同的结构体,将socket接收的数据拷贝到结构体中。需要⽤到 ctype 模块,ctypes是Python的⼀个外部库,提供和C语⾔兼容的数据类型,可以很⽅便地调⽤C 动态链接库中的函数。ctypes的类型对应如下:ctypes typec_charc_wcharc_bytec_ubytec_boolc_shortc_ushortc_intc_uintc_longc_ulongc_longlongc_ulonglongc_floatc_doublec_longdoublec_char_pC typecharwchar_tcharunsigned charboolshortunsigned shortintunsigned intlongunsigned long__int64 or longlongunsigned __int64 or unsigned long longfloatdoublelong double floatchar *Python Type1-character string1-character unicode stringint/longint/longboolint/longint/longint/longint/longint/longint/longint/longint/longfloatfloatfloatstring or Nonec_wchar_pctypes typec_void_pwchar_t *C typevoid *unicode or NonePython Typeint/long or None对应的指针类型是在后⾯加上"_p",如int*是c_int_p等等。在python中要实现c语⾔中的结构,需要⽤到类。下⾯是发送和接收的代码:发送端 struct_# -*- coding: utf-8 -*-import socketimport timeimport structfrom ctypes import *class Data(Structure): _pack_ = 1 #让结构体内存连续 _fields_ = [("member_1", c_ubyte), ("member_2", c_ubyte), ("member_3", c_float), ("member_4", c_float), ("member_5", c_double)]data = Data()_1= _2= _3= _4= _5= 1000PORT = 8000sender_socket = (_INET, _DGRAM)receiver_address = ("192.168.43.131", PORT)while True: start = () print(me('%Y-%m-%d %H:%M:%S', ime(start))) sender_(data, receiver_address) print 'member_1: %d' % _1, 'member_2: %d' % _2, 'member_3: %.2f' % _3, 'member_4: %.2f' % _4, 'member_5: %d' % _5 (1)接收端 struct_# -*- coding: utf-8 -*-import socketimport timeimport structfrom ctypes import *class Data(Structure): _pack_ = 1 _fields_ = [("member_1", c_ubyte), ("member_2", c_ubyte), ("member_3", c_float), ("member_4", c_float), ("member_5", c_double)]data = Data()PORT = 8000receiver_socket = (_INET, _DGRAM)address = ("192.168.43.131", PORT)receiver_(address)while True: now = () print(me('%Y-%m-%d %H:%M:%S',ime(now))) message, client = receiver_om(1024) memmove(addressof(data), (message), sizeof(Data)) print 'member_1: %d' % _1, 'member_2: %d' % _2, 'member_3: %.2f' % _3, 'member_4: %.2f' % _4, 'member_5: %d' % _5在pycharm中运⾏,结果如图:

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689410477a243573.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信