• Python TCP服务端多线程接收RFID网络读卡器上传数据


    本示例使用设备介绍:WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) 

    1. #python通过缩进来表示代码块,不可以随意更改每行前面的空白,否则程序会运行错误!!!如果缩进不一致,就会报错: IndentationError
    2. #!/usr/bin/env python
    3. # -*- coding: utf-8 -*-
    4. #python -m pdb xxx.py 调试程度 n命令单步执行,s命令单步执行 会进入函数内部 b xx ,c
    5. #import pdb pdb.set_trace() 设断点
    6. import sys
    7. import socketserver
    8. import os
    9. import socket
    10. import time
    11. import pdb
    12. class Server(socketserver.BaseRequestHandler):
    13. def handle(self):
    14. print("conn is :", self.request) # conn
    15. print("client_address is :", self.client_address) # addr
    16. while True:
    17. if self.request:
    18. # 接收收消息
    19. data = self.request.recv(1024).strip()
    20. if not data:
    21. print("no data break")
    22. break
    23. print("no data continue")
    24. continue
    25. GetData = 'Received from %s:%s' % (self.client_address) + " :"
    26. for num in range(0, len(data)):
    27. GetData = GetData + '%02X ' % (data[num])
    28. print(GetData)
    29. #解析接收到的数据
    30. if (data[0] == eval('0xC1') or data[0] == eval('0xCF')): # 接收IC读卡器上传的读卡号数据、IC卡离开读卡器的信息
    31. FunCode = '%02X' % (data[0])
    32. DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 设备IP
    33. DevNo = '%05d' % (data[5] + data[6] * 256) # 机号
    34. FrameNo = '%d' % (data[7] + data[8] * 256) # 数据包序号
    35. Cardlen=data[9]; #卡号长度
    36. Card16H="" #16进制卡号
    37. for num in range(10, 10+Cardlen):
    38. Card16H = Card16H + '%02X' % (data[num])
    39. Cardno = data[10] #转10进制卡号
    40. Cardno = Cardno + (data[11] * 256)
    41. Cardno = Cardno + (data[12] * 65536)
    42. Cardno = Cardno + (data[13] * 16777216)
    43. CardnoStr = '%010d' % Cardno
    44. SerialNum = '' # 设备硬件序列号
    45. for num in range(10+Cardlen, len(data)):
    46. SerialNum = SerialNum + '%02X' % (data[num])
    47. if (data[0] == eval('0xC1')):
    48. print('数据解析:IC读卡器刷卡数据,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo +",卡号长度:"+"%d" %(Cardlen)+ ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum+"\n")
    49. else:
    50. print('数据解析:IC卡离开读卡器,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo +",卡号长度:"+"%d" %(Cardlen)+ ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum + "\n")
    51. RespByte=GetResponseData(2) #根据不同情况生成要回应指令码
    52. self.request.sendall(RespByte) #发送回应指令码
    53. SendData = 'Send Data to %s:%s' % (self.client_address) + " :"
    54. for num in range(0, len(RespByte)):
    55. SendData = SendData + '%02X ' % (RespByte[num])
    56. print(SendData+"\n")
    57. elif (data[0] == eval('0xD1') or data[0] == eval('0xDF')): # 接收ID读卡器上传的读卡号数据、ID卡离开读卡器数据
    58. FunCode = '%02X' % (data[0])
    59. DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 设备IP
    60. DevNo = '%05d' % (data[5] + data[6] * 256) # 机号
    61. FrameNo = '%d' % (data[7] + data[8] * 256) # 数据包序号
    62. Card16H = '%02X%02X%02X%02X%02X' % (data[9],data[10], data[11], data[12], data[13]) # 16进制卡号
    63. Cardno = data[9] #转10进制卡事情
    64. Cardno = Cardno + (data[10] * 256)
    65. Cardno = Cardno + (data[11] * 65536)
    66. Cardno = Cardno + (data[12] * 16777216)
    67. CardnoStr = '%010d' % Cardno
    68. SerialNum = '' # 设备硬件序列号
    69. for num in range(14, len(data)):
    70. SerialNum = SerialNum + '%02X' % (data[num])
    71. if (data[0] == eval('0xD1')):
    72. print('数据解析:ID读卡器刷卡数据,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo + ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum + "\n")
    73. else:
    74. print('数据解析:ID卡离开读卡器,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo + ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum + "\n")
    75. RespByte = GetResponseData(2) # 根据不同情况生成要回应指令码
    76. self.request.sendall(RespByte) # 发送回应指令码
    77. SendData = 'Send Data to %s:%s' % (self.client_address) + " :"
    78. for num in range(0, len(RespByte)):
    79. SendData = SendData + '%02X ' % (RespByte[num])
    80. print(SendData + "\n")
    81. elif (data[0] == eval('0xF3')): # 接收到设备的心跳数据包,设备心跳间隔可根据协议自行设置
    82. FunCode = '%02X' % (data[0])
    83. DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 设备IP
    84. DevNo = '%05d' % (data[5] + data[6] * 256) # 机号
    85. FrameNo = '%d' % (data[7] + data[8] * 256) # 数据包序号
    86. heartbeattype='%02X' % (data[9])
    87. outleng='%d' % (data[10])
    88. switchon='%02X' % (data[11])
    89. inputinf='%02X' % (data[12])
    90. rand='%02X%02X%02X%02X' % (data[13], data[14], data[15], data[16])
    91. SerialNum = ''
    92. for num in range(17, len(data)):
    93. SerialNum = SerialNum + '%02X' % (data[num])
    94. print('接收数据解析:设备心跳包,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo + ",心跳类型:" + heartbeattype + ",长度:" + outleng+ ",继电器状态:" + switchon + ",输入接口状态:" + inputinf + ",随机校验码:" + rand + ",硬件序列号:" + SerialNum + "\n")
    95. def GetResponseData(respcode): # 生成不同的回应数据
    96. sdata=bytearray()
    97. if (respcode==0): # 生成蜂鸣响声的回应数据
    98. sdata.append(eval('0x96')) # 蜂鸣响声的指令码
    99. sdata.append(eval('0x00')) # 机号低
    100. sdata.append(eval('0x00')) # 机号高,0000表示任意机号
    101. sdata.append(eval('0x01')) # 蜂鸣响声代码,取值范围0-12
    102. elif(respcode==1): # 生成显示文字+蜂鸣响声的 回应数据
    103. DispStr = "本次刷卡成功,感谢您的使用,再见! "
    104. DispByte = bytes(DispStr, encoding='gbk') # 将要显示的文字转bytes
    105. DispByte = DispByte[0:34] # 两行屏可以显示34个字符
    106. CommByte=bytes([eval('0x5A'), 0, 0, 2, 30]) # 5A是指令码+2字节机号+1字节蜂鸣代码+1字节显示时长
    107. sdata = CommByte + DispByte # 加入显示文字的ASC码
    108. elif (respcode == 2): # 生成显示文字+蜂鸣响声的+继电器开关+TTS中文语音的 回应数据
    109. DispStr = "本次刷卡成功,感谢您的使用,再见! "
    110. DispByte = bytes(DispStr, encoding='gbk') # 将要显示的文字转bytes
    111. DispByte = DispByte[0:34] # 两行屏可以显示34个字符
    112. SpkStr = '[v1]欢迎您使用我们的网络读卡器,谢谢!' # 要播报的TTS语音,[v10]表示音量,取值0-16,可放置字符串的任意地方,一次最多126个字节
    113. Spkb = bytes(SpkStr, encoding='gbk') # 将要播报的TTS语音转bytes,
    114. Spkl = len(Spkb) # TTS语音长度
    115. sufb = bytes([eval('0x55'), eval('0xaa'), eval('0x66'), eval('0x99')]) # 固定的抗干扰后缀
    116. comb = bytes([eval('0x5C'), 0, 0, 1, eval('0xF0'), 20, 0, 20, 0, 34,Spkl]) # 5C是指令码+2字节机号+1字节蜂鸣代码+1字节继电器代码+2字节继电器延时+1字节显示时长+1字节显示起始位+1字节显示长度+1语音长度
    117. sdata = comb + DispByte + Spkb + sufb
    118. elif (respcode == 3): # 生成开启继电器开关的 回应数据
    119. sdata.append(eval('0x78')) # 蜂鸣响声的指令码
    120. sdata.append(eval('0x00')) # 机号低
    121. sdata.append(eval('0x00')) # 机号高,0000表示任意机号
    122. sdata.append(eval('0xF0')) # 继电器代码 F0表示全部继电器、F1表示1号继电器 、F2表示2号继电器......
    123. sdata.append(eval('0x2c')) # 继电器开启延时低位
    124. sdata.append(eval('0x01')) # 继电器开启延时高位,FFFF表示继电器一直开启
    125. return sdata
    126. if __name__ == "__main__":
    127. IpList = []
    128. if sys.platform == 'linux' or sys.platform == 'mac': # linux、mac系统获取电脑所有网卡IP
    129. ips = [ip.split('/')[0] for ip in os.popen("ip addr | grep 'inet '|awk '{print $2}'").readlines()]
    130. for i in ips:
    131. IpList.append(i)
    132. print('%d ' % (len(IpList)) + i)
    133. else:
    134. addrs = socket.getaddrinfo(socket.gethostname(), None) # windows获取电脑所有网卡IP
    135. for item in addrs:
    136. if ':' not in item[4][0]:
    137. IpList.append(item[4][0])
    138. print('%d ' % (len(IpList)) + item[4][0])
    139. Bindip = IpList[0] # 如有多张网卡,可选择绑定不同的网卡
    140. address = ('', 39169) # 未指定绑定网卡,可侦听本机所有网卡信息,读卡器出厂默认39169通讯端口
    141. with socketserver.ThreadingTCPServer(address, Server) as server:
    142. try:
    143. server.serve_forever()
    144. except Exception as e:
    145. print(e)
    146. pass
    147. pass

     

  • 相关阅读:
    mariadb galera 故障恢复
    动画沿椭圆路线进行旋转
    Openmp和MPI并行程序设计的区别
    自动驾驶人工智能
    python爬虫
    【跟学C++】C++栈——Stack类(Study12)
    Android逆向学习(五)app进行动态调试
    阿里云云原生一体化数仓 — 湖仓一体新能力解读
    大数据-各类图像数据集下载地址
    艾美捷专有脂质SM-102说明书
  • 原文地址:https://blog.csdn.net/zhangjin7422/article/details/134264209