tcp_client.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. # -*- coding:utf-8 -*-
  2. import os, sys, time
  3. import abc
  4. import socket
  5. import json
  6. import numpy as np
  7. import struct
  8. import binascii
  9. #创建ProHeader数据类型
  10. # 定义:
  11. DataHeader = np.dtype({'names': ['protocol', 'len', 'cmd'], 'formats': ['u1', 'u4', 'u1']}, align=False)
  12. UserInfo = np.dtype({'names': ['userName', 'password', 'actuator'], 'formats': ['|S260', '|S260', '|S260']}, align=False)
  13. LoginResp = np.dtype({'names': ['bStatus', 'szMessage'], 'formats': ['?', '|S260']}, align=False)
  14. # 通知SATService正常关机、重启;
  15. NoticeResp = np.dtype({'names': ['TimeStamp', 'NoticeType'], 'formats': ['u8', 'u4']}, align=False)
  16. class BaseClient(object):
  17. __metaclass__ = abc.ABCMeta
  18. def __init__(self):
  19. """设备id"""
  20. self.device_id = 1
  21. '''设备名称'''
  22. self.device_name = "name"
  23. '''设备命令'''
  24. self.device_cmd = "rtn 11;"
  25. '''设备通讯超时值:毫秒'''
  26. self.device_timeout = 300
  27. '''通信sock'''
  28. self.sock = None
  29. '''通信端口号'''
  30. self.port = 5588
  31. '''通信状态'''
  32. self.constate = False
  33. def __def__(self):
  34. self.disconnect()
  35. '''连接服务器'''
  36. def connect(self):
  37. try:
  38. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  39. self.sock.connect(('127.0.0.1', self.port)) # 没有返回值;
  40. self.sock.sendall("2222")
  41. self.constate = True
  42. except Exception, e:
  43. print "BaseClient=> socket connect error:", e, self.port
  44. self.constate = False
  45. return self.constate
  46. # 发送消息;
  47. def sendmsg(self):
  48. '''是否连接'''
  49. if self.constate is False:
  50. if self.connect() is False:
  51. return None
  52. '''拼装要发送的数据包'''
  53. userinfo = np.array([("superAdmin", "123456")], dtype=UserInfo)
  54. '''发送请求数据'''
  55. try:
  56. self.sock.settimeout(5)
  57. phead = np.array([(0xAA, userinfo.itemsize + np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize, 0x00)], dtype=DataHeader)
  58. '''一次性发送完整包'''
  59. # self.sock.sendall(bytearray(phead.tobytes() + bytes(msg_json)))
  60. '''分包发送:头、体'''
  61. self.sock.sendall(phead.tobytes())
  62. self.sock.sendall(userinfo.tobytes())
  63. self.sock.settimeout(None)
  64. except Exception, e:
  65. print "BaseClient=> send Error:", e
  66. self.disconnect()
  67. self.connect()
  68. return None
  69. '''接收返回数据'''
  70. try:
  71. # 等待数据返回;(串口若请求失败,超时值应该设置在3秒以上)
  72. self.sock.settimeout(10)
  73. data = bytes(self.sock.recv(1024 * 8))
  74. print "recv:" + binascii.hexlify(data)
  75. self.sock.settimeout(None)
  76. phead = data[0: np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize]
  77. respone = data[np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize:]
  78. print "respone:" + binascii.hexlify(respone)
  79. '''小端<I, 大端>I, 网络端 !'''
  80. protocol, len, cmd = struct.unpack('<BIB', phead)
  81. status, message = int(struct.unpack('<c', respone))
  82. '''返回头是否有效'''
  83. if protocol != 0xAA and len != data.__len__():
  84. return None
  85. return status
  86. except Exception, e:
  87. print "BaseClient=> recv Error:", e
  88. return None
  89. '''断开连接'''
  90. def disconnect(self):
  91. try:
  92. self.sock.shutdown(2)
  93. self.sock.close()
  94. except Exception, e:
  95. print "BaseClient=> socket disconnect error:", e
  96. class SATClient(object):
  97. __metaclass__ = abc.ABCMeta
  98. def __init__(self):
  99. '''通信sock'''
  100. self.sock = None
  101. '''通信端口号'''
  102. self.port = 5599
  103. '''通信状态'''
  104. self.constate = False
  105. def __def__(self):
  106. self.disconnect()
  107. '''连接服务器'''
  108. def connect(self):
  109. try:
  110. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  111. self.sock.connect(('127.0.0.1', self.port)) # 没有返回值;
  112. self.sock.sendall("2222")
  113. self.constate = True
  114. except Exception, e:
  115. print "BaseClient=> socket connect error:", e, self.port
  116. self.constate = False
  117. return self.constate
  118. # 发送消息;
  119. def sendmsg(self):
  120. '''是否连接'''
  121. if self.constate is False:
  122. if self.connect() is False:
  123. return None
  124. '''拼装要发送的数据包'''
  125. userinfo = np.array([("superAdmin", "123456", "SAT-Admin")], dtype=UserInfo)
  126. '''发送请求数据'''
  127. try:
  128. self.sock.settimeout(5)
  129. phead = np.array([(0xAA, userinfo.itemsize + np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize, 0x00)],
  130. dtype=DataHeader)
  131. '''一次性发送完整包'''
  132. # self.sock.sendall(bytearray(phead.tobytes() + bytes(msg_json)))
  133. '''分包发送:头、体'''
  134. self.sock.sendall(phead.tobytes())
  135. self.sock.sendall(userinfo.tobytes())
  136. self.sock.settimeout(None)
  137. except Exception, e:
  138. print "BaseClient=> send Error:", e
  139. self.disconnect()
  140. self.connect()
  141. return False
  142. # time.sleep(0.1)
  143. # return False
  144. '''接收返回数据'''
  145. try:
  146. # 等待数据返回;(串口若请求失败,超时值应该设置在3秒以上)
  147. self.sock.settimeout(10)
  148. data = bytes(self.sock.recv(1024 * 8))
  149. # print "recv:" + binascii.hexlify(data)
  150. self.sock.settimeout(None)
  151. phead = data[0: np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize]
  152. respone = data[np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize:]
  153. '''
  154. 注意:坑!
  155. 如果respone此时只返回16进制字符 '\x01',Python的字符与C++的不一样,字符就是字符;
  156. 要将16进制字符转成整型,使用ord函数
  157. '''
  158. # print "respone:" + binascii.hexlify(respone)
  159. '''小端<I, 大端>I, 网络端 !'''
  160. protocol, len, cmd = struct.unpack('<BIB', phead)
  161. # loginresult = ord(struct.unpack('<c', respone)[0])
  162. status, message = struct.unpack('<?260s', respone)
  163. '''返回头是否有效'''
  164. if protocol != 0xAA and len != data.__len__():
  165. return False
  166. return status
  167. except Exception, e:
  168. print "BaseClient=> recv Error:", e
  169. return False
  170. # 发送通知,不接收返回;
  171. def sendnotice(self, type):
  172. '''是否连接'''
  173. if self.constate is False:
  174. if self.connect() is False:
  175. return None
  176. '''拼装要发送的数据包'''
  177. notice = np.array([(time.time(), type)], dtype=NoticeResp)
  178. '''发送请求数据'''
  179. try:
  180. self.sock.settimeout(5)
  181. phead = np.array([(0xAA, notice.itemsize + np.array([(0xAA, 0, 0x01)], dtype=DataHeader).itemsize, 0x06)], dtype=DataHeader)
  182. '''一次性发送完整包'''
  183. self.sock.sendall(bytearray(phead.tobytes() + notice.tobytes()))
  184. self.sock.settimeout(None)
  185. except Exception, e:
  186. print "BaseClient=> send Error:", e
  187. self.disconnect()
  188. self.connect()
  189. return False
  190. '''断开连接'''
  191. def disconnect(self):
  192. try:
  193. self.sock.shutdown(2)
  194. self.sock.close()
  195. except Exception, e:
  196. print "BaseClient=> socket disconnect error:", e
  197. if __name__ == "__main__":
  198. bc = SATClient()
  199. while 1:
  200. print bc.sendmsg()
  201. print "ok!"