123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- # -*- 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, 大端>I, 网络端 !'''
- protocol, len, cmd = struct.unpack('<BIB', phead)
- status, message = int(struct.unpack('<c', respone))
- '''返回头是否有效'''
- if protocol != 0xAA and len != data.__len__():
- return None
-
- return status
- except Exception, e:
- print "BaseClient=> 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, 大端>I, 网络端 !'''
- protocol, len, cmd = struct.unpack('<BIB', phead)
- # loginresult = ord(struct.unpack('<c', respone)[0])
- status, message = struct.unpack('<?260s', respone)
- '''返回头是否有效'''
- if protocol != 0xAA and len != data.__len__():
- return False
- return status
- except Exception, e:
- print "BaseClient=> 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!"
|