2023-03-10 01:34:44 +00:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
#coding:utf-8
|
|
|
|
|
import socketserver
|
|
|
|
|
import subprocess
|
2023-03-10 09:58:19 +00:00
|
|
|
|
offs = 0 #偏移量
|
2023-03-10 01:34:44 +00:00
|
|
|
|
p ={}
|
|
|
|
|
#保存终端信息,ccid与地址对
|
|
|
|
|
#p={ccid=addr,}
|
|
|
|
|
#缓存未能正常发送消息的客户端
|
2023-03-10 09:58:19 +00:00
|
|
|
|
pp={}
|
2023-03-10 01:34:44 +00:00
|
|
|
|
cache=[]
|
|
|
|
|
|
2023-03-10 09:58:19 +00:00
|
|
|
|
|
|
|
|
|
def update_pairs(addr,ccid,clear=0):
|
|
|
|
|
'''更新终端库
|
|
|
|
|
addr:绑定tcp地址
|
|
|
|
|
ccid:终端号
|
|
|
|
|
clear:清空掉线终端'''
|
|
|
|
|
|
|
|
|
|
if ccid and not clear:
|
|
|
|
|
#添加或更新客户端
|
|
|
|
|
p[ccid] = addr
|
|
|
|
|
pp[addr] = ccid
|
|
|
|
|
else:
|
|
|
|
|
del p[ccid]
|
|
|
|
|
del pp[addr]
|
|
|
|
|
|
|
|
|
|
# 打印在线终端
|
|
|
|
|
for i in p:
|
|
|
|
|
print(i,"<--->",p[i])
|
|
|
|
|
# for i in pp:
|
|
|
|
|
# print(i,"-",pp[i])
|
|
|
|
|
|
|
|
|
|
def get_addr(ccid):
|
|
|
|
|
'''获取ccid对应的地址'''
|
|
|
|
|
|
2023-03-10 01:34:44 +00:00
|
|
|
|
try:
|
2023-03-10 09:58:19 +00:00
|
|
|
|
# 如果有直接返回
|
|
|
|
|
return p[ccid]
|
2023-03-10 01:34:44 +00:00
|
|
|
|
except Exception:
|
2023-03-10 09:58:19 +00:00
|
|
|
|
#没有就返回None
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def get_ccid(addr):
|
|
|
|
|
try:
|
|
|
|
|
# 如果有直接返回
|
|
|
|
|
return pp[addr]
|
|
|
|
|
except Exception:
|
|
|
|
|
#没有就返回None
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
+--------+--------------+----------+----------+--------------+------------------------+--------+
|
|
|
|
|
| ff | 长度 | 地址信息 | 信令 | 内容 | 校验位 |
|
|
|
|
|
+--------+--------------+----------+----------+--------------+------------------------+--------+
|
|
|
|
|
| | 2Bytes | 4Bytes | 心跳 | 0x01 | 时间戳32bit(单位ms) | 2Bytes |
|
|
|
|
|
+ $TTMS +--------------+----------+----------+--------------+------------------------+--------+
|
|
|
|
|
| | 2Bytes | 4Bytes | 传输数据 | 0xaa | 载荷 | 2Bytes |
|
|
|
|
|
+--------+--------------+----------+----------+--------------+------------------------+--------+
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
def tt_hh(addr,data):
|
|
|
|
|
'''处理心跳'''
|
|
|
|
|
|
|
|
|
|
# 更新pairs
|
|
|
|
|
update_pairs(addr,data[7+offs:11+offs])
|
|
|
|
|
# 组帧再返回
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def tt_trans(addr,data):
|
|
|
|
|
'''发送数据到指定ccid'''
|
|
|
|
|
|
|
|
|
|
tccid = data[7+offs:11+offs]
|
|
|
|
|
taddr = get_addr(tccid)
|
|
|
|
|
if not taddr:
|
|
|
|
|
print("未找到在线终端,可能终端未在线或ccid错。")
|
|
|
|
|
return 0
|
|
|
|
|
print("找到匹配终端:",tccid,"<--->",taddr)
|
|
|
|
|
# 组帧
|
|
|
|
|
msg = bytearray(data[:])
|
|
|
|
|
msg[:5]=b'$TMMX'
|
|
|
|
|
msg[7+offs:11+offs] = get_ccid(addr)
|
|
|
|
|
|
|
|
|
|
# 计算校验和
|
|
|
|
|
crc = 0
|
|
|
|
|
for i in msg[:-2]:
|
|
|
|
|
crc = crc ^ i
|
|
|
|
|
msg[-1]=crc
|
|
|
|
|
|
|
|
|
|
# 发送
|
|
|
|
|
try:
|
|
|
|
|
taddr.send(msg)
|
|
|
|
|
except Exception:
|
|
|
|
|
# 更新pairs
|
|
|
|
|
update_pairs(taddr,tccid,1)
|
|
|
|
|
print("终端已掉线。",taddr)
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def err_handle(flag,addr):
|
|
|
|
|
'''错误处理
|
|
|
|
|
|
|
|
|
|
默认打印错误信息
|
|
|
|
|
|
|
|
|
|
1-非法连接,关闭连接
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def tt_decode(addr,data):
|
|
|
|
|
'''处理收到的数据'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if data[:5].hex() != "2454544d53" or len(data) <12:
|
|
|
|
|
# 数据长度不可能小于12,考虑非法接入的可能,主动断开连接
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cmd = data[11+offs]
|
|
|
|
|
if cmd==0x01:
|
|
|
|
|
# 处理心跳
|
|
|
|
|
tt_hh(addr,data)
|
|
|
|
|
elif cmd==0xaa:
|
|
|
|
|
# 处理数据
|
|
|
|
|
tt_trans(addr,data)
|
|
|
|
|
else:
|
|
|
|
|
return -1
|
|
|
|
|
|
2023-03-10 01:34:44 +00:00
|
|
|
|
|
|
|
|
|
class MyServer(socketserver.BaseRequestHandler):
|
|
|
|
|
def handle(self):#回调
|
|
|
|
|
print ("终端已上线:",self.client_address)
|
|
|
|
|
conn = self.request
|
2023-03-10 09:58:19 +00:00
|
|
|
|
# print(type(conn),conn.fd)
|
2023-03-10 01:34:44 +00:00
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
data = conn.recv(200)
|
2023-03-10 09:58:19 +00:00
|
|
|
|
# update_pairs(conn,data[7+offs:11+offs])
|
2023-03-10 01:34:44 +00:00
|
|
|
|
if not data:
|
|
|
|
|
break
|
|
|
|
|
print ("接收到新数据",self.client_address,",长度",len(data),":\r\n", data.hex(" "))
|
|
|
|
|
#ack_msg = "got from "+ str(ip) + " to " + str(self.client_address) + data
|
2023-03-10 09:58:19 +00:00
|
|
|
|
# conn.send(data[:6])
|
|
|
|
|
if tt_decode(conn,data) :
|
|
|
|
|
conn.close()
|
|
|
|
|
print(self.client_address,"疑是非法连接,已切断。")
|
|
|
|
|
break
|
|
|
|
|
|
2023-03-10 01:34:44 +00:00
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
server = socketserver.ThreadingTCPServer(('localhost',8005), MyServer)
|
|
|
|
|
ip, port = server.server_address
|
|
|
|
|
print ("服务端已建立:",ip, port)
|
|
|
|
|
server.serve_forever()
|
|
|
|
|
|