python多线程下tcp服务端,数据实时动态打包发送

因为要通过电脑和树莓派在局域网(这里是在我的同一个wifi热点下),进行数据传递(主要是传递摄像头收回的图像坐标包,但是机器学习识别率在复杂场景下太尴尬了,等题主我多学习学习神经网络识别的代码后,再来奥利给个新博客)

好的上面只是简单的介绍一下背景,这里说一下开花环境:
环境: win7 x64 python3.6
通信架构: tcp
目标:用python写一个服务端程序,然后不停的通过这个程序发送特定的按照时刻规律变化的数据,这里暂定为五个.

好的,开始开花

1.定义数据类

顾名思义,既然我们要发送特定的按照时刻规律变化的数据,我们得先定义好我们要准备的数据,在c/c++里面类似struct,而python则使用类的方法,如下我们定义了一个叫Send_Data的类,如下所示里面共有6个初始数据,并定义了re_data方法,返回打包数据


class Send_Data(object):
    def __init__(self):
        self.zuo_you = 111
        self.qian_hou = 222
        self.cha_zuo_you = 0
        self.cha_qian_hou = 1
        self.relative_distance = 333
        self.zong_data = "000000000000000000"
    def re_data(self):
        self.zong_data = bu_three(self.zuo_you) + bu_three(self.qian_hou) + bu_three(self.relative_distance) + bu_three(self.cha_zuo_you) + bu_three(self.cha_qian_hou)
        return self.zong_data

注:bu_three函数的作用是将内部的数据转换成字符并统计长度大小.若长度大小为1或2则在前面补零,为3则不变,超过3则返回err,具体函数如下:


def bu_three(three):#补齐3位字符串
    three = str(three)
    if(len(three) == 1):
        three = "00" + three
        return three
    elif(len(three) == 2):
        three ="0" + three
        return three
    elif(len(three) == 3):
        return three
    else:
        return " err"  # 当超过3或为0时返回错误 err (error)

2.设置tcp通信

以下是一个用python3.6写的tcp服务端的程序


def change_utf():
   
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("填写局域网内你要链接的设备ip", 9999))
    s.listen(5)
    print("等待连接...")

    while True:
        sock, addr = s.accept()
        t = threading.Thread(target=tcplink, args=(sock, addr))
        t.start()


def tcplink(sock, addr):
    print("正在连接从 %s:%s" % (addr))
    #sock.send(bytes(data_x,encoding='utf-8'))#b表示二进制
    while True:
        zong_data = send_data.re_data()
        print("开始发送数据 滴滴")

        sock.send(zong_data.encode())
        time.sleep(0.03)
        #print(send_buf.encode())
        data = sock.recv(64)
        #time.sleep(0.03)
        if not data or data.decode('utf-8') == 'exit':
            break
        #sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
        print('%s!' % data.decode('utf-8'))#打印客户端消息
        #print("\n", end="")
        print("\n")
       # send_buf.clear()#清空列表

 
    sock.close()
    print("连接从 %s:%s 断开" % (addr))

这时我们就可以开启服务端给客户端发送没有改变的数据了(这里的客户端我是用的c++写的哈),通过线程的调用方式如下

send_data = Send_Data()
t2 = threading.Thread(target=change_utf)
t2.start()

程序运行示意图(如下)
在这里插入图片描述

3.设置另一个线程动态的实时修改数据参数

这里的思路呢,是先在Send_Data类里定义一个处理方法deal_data,在本程序中这个方法在使用时可以改变send_data.cha_zuo_you,和 send_data.qian_hou的值 (如下):

 def deal_data(self):
        while (1):
            send_data.cha_zuo_you += 1
            send_data.qian_hou += 2
            time.sleep(0.5)

之后呢,在一个线程(或在调用另一个线程后的主程序下)中调用这个方法,(如下,这里是在一个线程中,send_data是之前定义的哈,莫搞忘了):

def tt():
    send_data.deal_data()

t3 = threading.Thread(target=tt, args=() )
t3.start()

4.再定义一个打印改变值的线程


def dayin(t):
    while (1):
        zong_data = send_data.re_data()
        print(zong_data)
        time.sleep(t)


send_data = Send_Data()
t2 = threading.Thread(target=dayin, args=(1,))
t2.start()

特别注意python线程传递值时的参数args=(1,),(这里的1后面是有一个逗号的,我已经忘了很多次了, 呱唧呱唧…到这里改变值的程序就完了,就这里而言是每隔1秒打印一次zong_data的值,而zong_data的值中的send_data.cha_zuo_you,和 send_data.qian_hou每过0.5秒,便加1和加2
运行示意图:
在这里插入图片描述

改变加入tcp线程

就是把zong_data = send_data.re_data()塞到tcp的tcplink线程里面去,就像下面一样,就是while True下面那一坨咯,记得把tt线程加上去哦


def tcplink(sock, addr):
    print("正在连接从 %s:%s" % (addr))
    #sock.send(bytes(data_x,encoding='utf-8'))#b表示二进制
    while True:
        zong_data = send_data.re_data()
       # print(zong_data)

        sock.send(zong_data.encode())
        time.sleep(0.03)
        #print(send_buf.encode())
        data = sock.recv(64)
        #time.sleep(0.03)
        if not data or data.decode('utf-8') == 'exit':
            break
        #sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
        print('%s!' % data.decode('utf-8'))#打印客户端消息
        #print("\n", end="")
        print("\n")
       # send_buf.clear()#清空列表


    sock.close()
    print("连接从 %s:%s 断开" % (addr))

和c++那边客户端连接的示意图:
在这里插入图片描述

代码上面都是全的(没有写import(摊手)),当然要拼一下咯.本文通过一个线程改变另一个线程中程序运行的值,主要是对python中类的存储区的操作,因为你会惊奇的发现(主要是惊奇自己为啥早没想到,反正我之前没想到咯(狗头)),你在tcplink线程中调用的zong_data = send_data.re_data()中的re_data()方法和tt线程中调用的deal_data()方法,都是在之前定义的Send_Data这个大类的空间下(如下图,看到自己文章被推了,又补的一张图哦 哈哈)
在这里插入图片描述
(因为python底层是c写的咯,如果有小伙伴对上面那张图的具体操作了解得更深一些,你可以点个赞,然后看我这篇博客(那个博客我画的图比上面这个好看)点击进入

不过呢,那个也只是,从让人从c语言对一个区域(c语言的struct)内的地址和地址中存储的值,怎样在c语言中通过指针连接与理解, 若还有再深入建议大家(有能力的大佬)看董少的博客中类继承与malloc函数解析等等等等(而我瑟瑟发抖) 江南、董少博客)

随便说一下,程序意外关闭的话,线程没有正确回收.第二次就程序就运行不了的哦,用任务管理器(我用的火绒剑)找到那个程序关闭后再开就行了

资源审核完毕

本程序资源(还是1个下载卷(我觉得我真是良心呀),当然其实代码基本都在上面的哈(摊手)):下载
本程序对应的c++客户端资源(不用下载卷,这个代码基本上是csdn上大佬写的,不好意思收咯):下载

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员进化不脱发!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值