#!/usr/bin/env python #coding:utf-8 import socketserver import subprocess offs = 0 #偏移量 p ={} #保存终端信息,ccid与地址对 #p={ccid=addr,} #缓存未能正常发送消息的客户端 pp={} cache=[] 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对应的地址''' try: # 如果有直接返回 return p[ccid] except Exception: #没有就返回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 class MyServer(socketserver.BaseRequestHandler): def handle(self):#回调 print ("终端已上线:",self.client_address) conn = self.request # print(type(conn),conn.fd) while True: data = conn.recv(200) # update_pairs(conn,data[7+offs:11+offs]) 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 # conn.send(data[:6]) if tt_decode(conn,data) : conn.close() print(self.client_address,"疑是非法连接,已切断。") break if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('localhost',8005), MyServer) ip, port = server.server_address print ("服务端已建立:",ip, port) server.serve_forever()