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


    给出程序先:

    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=b'E'
            self.latDir=b'N'
            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 {}:{}	
    {}".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

  • 相关阅读:
    bzoj1081 [SCOI2005]超级格雷码
    bzoj3790 神奇项链
    bzoj2822 [AHOI2012]树屋阶梯
    bzoj1485 [HNOI2009]有趣的数列
    bzoj1486 [HNOI2009]最小圈
    bzoj2721 [Violet 5]樱花
    POJ 1238 Substrings
    ZOJ Team Formation
    POJ 1459 Power Network
    POJ 1458 Common Subsequence
  • 原文地址:https://www.cnblogs.com/superxuezhazha/p/11497895.html
Copyright © 2020-2023  润新知