#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import socket import os import time import logging import sys # reload(sys) 和 sys.setdefaultencoding('utf-8') 在 Python 3 中不再需要 if __name__ == '__main__': #======修改以下参数====== TmsServerIp='192.168.8.9' #TMS服务器IP,用于绑定服务,等待外部指令 TmsPor='10129' #TMS服务器端口,用于绑定服务,等待外部指令 upc_dev_ip="192.168.8.125" #自动化控制设备IP upc_dev_port="502" #自动化控制设备端口 # 注意:Senderfile 指向的 sender.py 脚本也需要是 Python 3 版本! Senderfile='/opt/upc_resent/bin/sender.py' #发送程序位置 Logfile='/opt/upc_resent/log/192.168.8.125.log' #日志文件位置 pythonpath="/usr/bin/python3" # Python 3 执行文件的位置,可在操作系统中使用which python3命令获取 #======================== BUFSIZE = 1024 # 配置日志,只执行一次 logging.basicConfig(filename=Logfile,filemode="a", level=logging.DEBUG) ISOTIMEFORMAT='%Y-%m-%d %X' sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.bind((TmsServerIp, int(TmsPor))) #启动TMS本地服务,等待外部设备发送指令 sock.listen(500) except OSError as e: # 在 Python 3 中使用 OSError 替代 socket.error logstr="!!!!!ERROR!!!!!"+time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )+" 无法绑定端口 %s:%s - %s" % (TmsServerIp, TmsPor, e) logging.error(logstr) print(logstr) # Python 3 print 函数 sys.exit(1) # 绑定失败则退出 logging.info("服务启动,监听 %s:%s" % (TmsServerIp, TmsPor)) while True: connection,address = sock.accept() try: connection.settimeout(5) #GDC系统长连接 # 接收到的数据是 bytes,需要解码成 str 进行比较 buf_bytes = connection.recv(BUFSIZE) buf = buf_bytes.decode('utf-8').strip() # 解码成 str 并移除空白符 operation = "nodata" # 默认值,如果没有匹配的命令 datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) ) logstr="==="+datetime_str+"收到客户端"+ address[0]+":"+str(address[1])+"发送的指令: '" +str(buf)+"'" logging.info(logstr) # 根据接收到的外部命令,映射到单个内部操作指令 if buf == 'open': operation = 'openall4' elif buf == 'close': operation = 'closeall4' elif buf == 'open1': operation = 'open1' elif buf == 'close1': operation = 'close1' elif buf == 'open2': operation = 'open2' elif buf == 'close2': operation = 'close2' elif buf == 'open3': operation = 'open3' elif buf == 'close3': operation = 'close3' elif buf == 'open4': operation = 'open4' elif buf == 'close4': operation = 'close4' elif buf == 'open5': # 新增 5-8 路的命令映射 operation = 'open5' elif buf == 'close5': operation = 'close5' elif buf == 'open6': operation = 'open6' elif buf == 'close6': operation = 'close6' elif buf == 'open7': operation = 'open7' elif buf == 'close7': operation = 'close7' elif buf == 'open8': operation = 'open8' elif buf == 'close8': operation = 'close8' elif buf == 'guanggao-guan': # 外部命令 'guanggao-guan' 映射到 'closeall4' (全关) operation = 'closeall4' # else: operation 保持为 "nodata" if operation == "nodata": logstr="==="+datetime_str+" 未知指令: '" +str(buf)+"'" logging.warning(logstr) print(logstr) # Python 3 print 函数 # 给客户端一个反馈,需要编码成 bytes connection.send(('Unknown command: %s' % buf).encode('utf-8')) else: logstr="==="+datetime_str+" 映射到内部指令: '" +str(operation)+"'" logging.info(logstr) # 直接执行一次外部脚本 os_command=str(pythonpath)+" " +Senderfile+ " " + str(upc_dev_ip)+" "+str(upc_dev_port)+" "+str(operation)+" "+str(Logfile) logging.info("执行外部命令: %s" % os_command) os.system(os_command) # 执行发送指令的脚本 # 成功处理后给客户端反馈,需要编码成 bytes connection.send(('Command %s processed as %s' % (buf, operation)).encode('utf-8')) except socket.timeout: datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) ) logstr="==="+datetime_str+" 客户端连接超时: "+ address[0]+":"+str(address[1])+"===" logging.warning(logstr) print('time out') # Python 3 print 函数 except Exception as e: # 捕获其他可能的异常 datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) ) logstr="==="+datetime_str+" 处理客户端 "+ address[0]+":"+str(address[1])+" 请求时发生错误: "+str(e)+"===" logging.error(logstr, exc_info=True) # 记录异常详情 print("Error processing request:", e) # Python 3 print 函数 # 给客户端一个错误反馈,需要编码成 bytes connection.send(('Error processing command: %s' % str(e)).encode('utf-8')) finally: connection.close() # 确保每次连接都被关闭