# -*- coding:utf-8 -*- import os, sys, time import abc import socket import json import numpy as np import struct import binascii #创建ProHeader数据类型 # 定义: DataHeader = np.dtype({'names': ['protocol', 'len', 'cmd'], 'formats': ['u1', 'u4', 'u1']}, align=False) UserInfo = np.dtype({'names': ['userName', 'password', 'actuator'], 'formats': ['|S260', '|S260', '|S260']}, align=False) LoginResp = np.dtype({'names': ['bStatus', 'szMessage'], 'formats': ['?', '|S260']}, align=False) # 通知SATService正常关机、重启; NoticeResp = np.dtype({'names': ['TimeStamp', 'NoticeType'], 'formats': ['u8', 'u4']}, align=False) class BaseClient(object): __metaclass__ = abc.ABCMeta def __init__(self): """设备id""" self.device_id = 1 '''设备名称''' self.device_name = "name" '''设备命令''' self.device_cmd = "rtn 11;" '''设备通讯超时值:毫秒''' self.device_timeout = 300 '''通信sock''' self.sock = None '''通信端口号''' self.port = 5588 '''通信状态''' self.constate = False def __def__(self): self.disconnect() '''连接服务器''' def connect(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect(('127.0.0.1', self.port)) # 没有返回值; self.sock.sendall("2222") self.constate = True except Exception, e: print "BaseClient=> socket connect error:", e, self.port self.constate = False return self.constate # 发送消息; def sendmsg(self): '''是否连接''' if self.constate is False: if self.connect() is False: return None '''拼装要发送的数据包''' userinfo = np.array([("superAdmin", "123456")], dtype=UserInfo) '''发送请求数据''' try: self.sock.settimeout(5) phead = np.array([(0xAA, userinfo.itemsize + np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize, 0x00)], dtype=DataHeader) '''一次性发送完整包''' # self.sock.sendall(bytearray(phead.tobytes() + bytes(msg_json))) '''分包发送:头、体''' self.sock.sendall(phead.tobytes()) self.sock.sendall(userinfo.tobytes()) self.sock.settimeout(None) except Exception, e: print "BaseClient=> send Error:", e self.disconnect() self.connect() return None '''接收返回数据''' try: # 等待数据返回;(串口若请求失败,超时值应该设置在3秒以上) self.sock.settimeout(10) data = bytes(self.sock.recv(1024 * 8)) print "recv:" + binascii.hexlify(data) self.sock.settimeout(None) phead = data[0: np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize] respone = data[np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize:] print "respone:" + binascii.hexlify(respone) '''小端I, 网络端 !''' protocol, len, cmd = struct.unpack(' recv Error:", e return None '''断开连接''' def disconnect(self): try: self.sock.shutdown(2) self.sock.close() except Exception, e: print "BaseClient=> socket disconnect error:", e class SATClient(object): __metaclass__ = abc.ABCMeta def __init__(self): '''通信sock''' self.sock = None '''通信端口号''' self.port = 5599 '''通信状态''' self.constate = False def __def__(self): self.disconnect() '''连接服务器''' def connect(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect(('127.0.0.1', self.port)) # 没有返回值; self.sock.sendall("2222") self.constate = True except Exception, e: print "BaseClient=> socket connect error:", e, self.port self.constate = False return self.constate # 发送消息; def sendmsg(self): '''是否连接''' if self.constate is False: if self.connect() is False: return None '''拼装要发送的数据包''' userinfo = np.array([("superAdmin", "123456", "SAT-Admin")], dtype=UserInfo) '''发送请求数据''' try: self.sock.settimeout(5) phead = np.array([(0xAA, userinfo.itemsize + np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize, 0x00)], dtype=DataHeader) '''一次性发送完整包''' # self.sock.sendall(bytearray(phead.tobytes() + bytes(msg_json))) '''分包发送:头、体''' self.sock.sendall(phead.tobytes()) self.sock.sendall(userinfo.tobytes()) self.sock.settimeout(None) except Exception, e: print "BaseClient=> send Error:", e self.disconnect() self.connect() return False # time.sleep(0.1) # return False '''接收返回数据''' try: # 等待数据返回;(串口若请求失败,超时值应该设置在3秒以上) self.sock.settimeout(10) data = bytes(self.sock.recv(1024 * 8)) # print "recv:" + binascii.hexlify(data) self.sock.settimeout(None) phead = data[0: np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize] respone = data[np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize:] ''' 注意:坑! 如果respone此时只返回16进制字符 '\x01',Python的字符与C++的不一样,字符就是字符; 要将16进制字符转成整型,使用ord函数 ''' # print "respone:" + binascii.hexlify(respone) '''小端I, 网络端 !''' protocol, len, cmd = struct.unpack(' recv Error:", e return False # 发送通知,不接收返回; def sendnotice(self, type): '''是否连接''' if self.constate is False: if self.connect() is False: return None '''拼装要发送的数据包''' notice = np.array([(time.time(), type)], dtype=NoticeResp) '''发送请求数据''' try: self.sock.settimeout(5) phead = np.array([(0xAA, notice.itemsize + np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize, 0x06)], dtype=DataHeader) '''一次性发送完整包''' self.sock.sendall(bytearray(phead.tobytes() + notice.tobytes())) self.sock.settimeout(None) except Exception, e: print "BaseClient=> send Error:", e self.disconnect() self.connect() return False '''断开连接''' def disconnect(self): try: self.sock.shutdown(2) self.sock.close() except Exception, e: print "BaseClient=> socket disconnect error:", e if __name__ == "__main__": bc = SATClient() while 1: print bc.sendmsg() print "ok!"