您的位置:首页 > 编程语言 > Python开发

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

2020-03-28 20:14 981 查看

因为要通过电脑和树莓派在局域网(这里是在我的同一个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上大佬写的,不好意思收咯):下载

  • 点赞
  • 收藏
  • 分享
  • 文章举报
知了的树 发布了6 篇原创文章 · 获赞 1 · 访问量 165 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: