首页 > 编程语言 > 详细

pythonUDP发送结构体,对齐到C++结构体

时间:2019-09-10 16:22:17      阅读:249      评论:0      收藏:0      [点我收藏+]

给出程序先:

技术分享图片
import random
import socket
import struct
import threading
import pickle
import json
from struct import *
from time import sleep


class sendMsg:
    def __init__(self):
        self.sendType=b\x01#ready
        self.cliType=b\x01
        self.lonDir=bE
        self.latDir=bN
        self.cliNum=1
        self.lonDeg=100
        self.lonMin=100
        self.lonSec=100
        self.latDeg=100
        self.latMin=100
        self.latSec=100
        self.year=2019
        self.month=9
        self.day=6
        self.hour=12
        self.minute=10
        self.second=10
        self.ipFirst=192
        self.ipSecond=168
        self.ipThird=6
        self.ipFourth=108
        self.typeStr=cccciiiiiiiiiiiiiiiii

    def __str__(self):
        return self.cliNum
class RecMsg():
    def __init__(self):
        self.id=b\x02
        self.ipFirst=192
        self.ipSecond=168
        self.ipThird=6
        self.ipFourth=108
        self.port=-1
        self.errorType=b\x01
        self.bandWidth=-1
        self.typeStr==ciiiiici


class CommunateThread(threading.Thread):  # 继承父类threading.Thread
    def __init__(self, id,packetLoss,socket,localIP,localPort,remoteIP,remotePort,file):
        threading.Thread.__init__(self)
        self.id=id
        self.packetLoss=packetLoss
        self.socket=socket
        self.localIP = localIP
        self.localPort=localPort
        self.remoteIP = remoteIP
        self.remotePort=remotePort
        self.file=file
    def run(self):  # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
        connect=False
        while True:
            if not connect:
                self.sendConnect()
            data, addr = self.socket.recvfrom(1024)
            print("接收到{}发送的消息{}".format(addr,data))
            recMes = RecMsg()
            recData = struct.unpack(recMes.typeStr,data)
            print(recData)
            if recData[0]==b\x01 or (recData[0]==b\x03 and recData[6]==b\x01):
                self.sendFile(recData)
    def readFile(self):
        with open(self.file,"rb") as f:
            data = f.read(1024)
            while data:
                yield data
                data=f.read(1024)
    def sendFile(self,recData):
        ip = "{}.{}.{}.{}".format(recData[1],recData[2],recData[3],recData[4])
        port = recData[5]
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            i =1
            for data in self.readFile():
                p = random.randint(1,100)
                if p<self.packetLoss:
                    continue
                s.sendto(data,(ip,port))
                sleep(0.005)
                i+=1
                if i%1000:
                    print(i," : send to {}:{},1k".format(ip,port))

            print("发送完成,总计发送 {} K".format(i))
        except Exception as e:
            print(e)
    def sendConnect(self):
        connect =sendMsg()
        connect.cliNum=self.id
        data=pack(  connect.typeStr,
                    connect.sendType,
                    connect.cliType,
                    connect.lonDir,
                    connect.latDir,
                    connect.cliNum,
                    connect.lonDeg,
                    connect.lonMin,
                    connect.lonSec,
                    connect.latDeg,
                    connect.latMin,
                    connect.latSec,
                    connect.year,
                    connect.month,
                    connect.day,
                    connect.hour,
                    connect.minute,
                    connect.second,
                    connect.ipFirst,
                    connect.ipSecond,
                    connect.ipThird,
                    connect.ipFourth)
        #data=pack(‘ccccb‘,connect.sendType,connect.cliType,connect.lonDir,connect.lonDir,connect.year)
        print(data)
        self.socket.sendto(data,(self.remoteIP,self.remotePort))
        print("send to {}:{}\t\n{}".format(self.remoteIP,self.remotePort,connect.__str__()))
def print_time(threadName, delay, counter):
    pass
View Code

急着把消息发出去,所以代码有点乱,也没有注释,嘻嘻。

我们知道python 使用UDP发送消息,只能发送byte出去。那么,如何和一个c++(c#)的结构体进行打包和解包呢?使用pack和unpack就可以了。

比如说我们的结构体是 这样的

技术分享图片

 

 它们分别是char 和int型的数据。我们这样把这个结构体(暂且认为是结构体吧)打包成字节流:

技术分享图片

 

 我这样打包,直接发送出去,字节数为 1(字符/char)*4 + 4(int) *17 = 32 位。用c++/c#接收,没有什么问题的。

但是接收的时候,出现无法对齐的问题。所以我们对接收的解包格式这样定义:

技术分享图片

 

 至于为什么加一个“=”,可以查阅python的文档,有详细的解释。

中文版:https://docs.python.org/zh-cn/3.6/library/struct.html

英文版:https://docs.python.org/3.6/library/struct.html

pythonUDP发送结构体,对齐到C++结构体

原文:https://www.cnblogs.com/superxuezhazha/p/11497895.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!