1.思路
接收设备的数据:写一个tcp服务器,设备主动连接的时候会发出数据,通过服务器接受到的数据进行转发,业务层去解析即可。
主动下发指令:需要写一个tcp服务器和tcp客户端,当设备来数据的肯定会带有设备的唯一标识,例如设备号、设备id等,接到设备数据后把设备号解析出来与本次连接进行绑定,存到缓存中以便主动下发指令的精准找到设备连接,把客户端作为一个rest服务,当我们主动下发指令的时候调用这个rest服务,这时候下发的指令数据中带有设备号,通过设备号精确的找到下发指令的设备,来实现下发。
2.代码
客户端
import json
import socket
from flask import Flask, request
server = Flask(__name__)
@server.route("/push",methods=['post'])
def main():
# 1 创建tcp套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2 创建连接
tcp_socket.connect(('127.0.0.1', 6666))
# 3 发送数据
data = json.loads(request.data)
tcp_input = request.data
tcp_socket.send(tcp_input) # utf-8 中文会乱码
# 4.关闭套接字
tcp_socket.close()
return ""
if __name__ == '__main__':
# test()
server.run(host="0.0.0.0",port=8787, debug=True)
服务端
import binascii
import json
import socket
from flask import Flask, request
import select
import redis
server = Flask(__name__)
# 内存
redis = redis.Redis(host='127.0.0.1', port=6379,db=0)
# 创建套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置可以重复使用绑定的信息
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 绑定本机信息
s.bind(("",6666))
# 变为被动
s.listen(10)
# 创建一个epoll对象
epoll=select.epoll()
# 测试,用来打印套接字对应的文件描述符
# print s.fileno()
# print select.EPOLLIN|select.EPOLLET
# 注册事件到epoll中
# epoll.register(fd[, eventmask])
# 注意,如果fd已经注册过,则会发生异常
# 将创建的套接字添加到epoll的事件监听中
epoll.register(s.fileno(),select.EPOLLIN|select.EPOLLET)
connections = {}
addresses = {}
# 循环等待客户端的到来或者对方发送数据
while True:
# epoll 进行 fd 扫描的地方 -- 未指定超时时间则为阻塞等待
epoll_list=epoll.poll()
# 对事件进行判断
for fd,events in epoll_list:
# print fd
# print events
# 如果是socket创建的套接字被激活
if fd == s.fileno():
conn,addr=s.accept()
print('有新的客户端到来%s'%str(addr))
# 将 conn 和 addr 信息分别保存起来
connections[conn.fileno()] = conn
addresses[conn.fileno()] = addr
print("conn.fileno()%s"%str(conn.fileno()))
# 向 epoll 中注册 连接 socket 的 可读 事件
epoll.register(conn.fileno(), select.EPOLLIN | select.EPOLLET)
elif events == select.EPOLLIN:
# 从激活 fd 上接收下发
recvData = connections[fd].recv(1024)
print('连接%s'%str(fd))
if len(recvData)>0:
print('recv:%s'%recvData)
issued = {}
try:
issued = recvData.decode(encoding='utf-8',errors='strict')
except Exception:
print("自动")
finally:
number = ''
if 'number' in issued:
print(issued)
issued = json.loads(issued)
print(issued)
# number = issued.get('number')
number = issued['number']
print(number)
fd2 = redis.get(str(number))
print(fd2)
content = '2000'
fd2 = fd2.decode(encoding='utf-8', errors='strict')
connections[int(fd2)].send(content.encode("utf-8"))
else:
data = binascii.b2a_hex(recvData)
print(data)
data = data.decode(encoding ='utf-8',errors = 'strict')
tou = '7a7a'
if tou in data:
numberKey = data[4:14]
redis.set(numberKey,fd)
print(data)
content = '200'
print('打印number'+number)
connections[fd].send(content.encode("utf-8"))
else:
# 从 epoll 中移除该 连接 fd
epoll.unregister(fd)
# server 侧主动关闭该 连接 fd
connections[fd].close()
print("%s---offline---"%str(addresses[fd]))
写的不好将就看吧,可以留言一起学习。