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

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

python 复制代码
#python通过缩进来表示代码块,不可以随意更改每行前面的空白,否则程序会运行错误!!!如果缩进不一致,就会报错: IndentationError
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#python -m pdb xxx.py 调试程度 n命令单步执行,s命令单步执行 会进入函数内部  b xx ,c
#import pdb    pdb.set_trace() 设断点

import sys
import socketserver
import os
import socket
import time
import pdb

class Server(socketserver.BaseRequestHandler):
    def handle(self):
        print("conn is :", self.request)  # conn
        print("client_address is :", self.client_address)  # addr

        while True:
            if self.request:
                # 接收收消息
                data = self.request.recv(1024).strip()
                if not data:
                    print("no data break")
                    break
                    print("no data continue")
                    continue

                GetData = 'Received from %s:%s' % (self.client_address) + " :"
                for num in range(0, len(data)):
                    GetData = GetData + '%02X ' % (data[num])
                print(GetData)

                #解析接收到的数据
                if (data[0] == eval('0xC1') or data[0] == eval('0xCF')):  # 接收IC读卡器上传的读卡号数据、IC卡离开读卡器的信息
                    FunCode = '%02X' % (data[0])
                    DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])  # 设备IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 机号
                    FrameNo = '%d' % (data[7] + data[8] * 256)  # 数据包序号
                    Cardlen=data[9];    #卡号长度
                    Card16H=""          #16进制卡号
                    for num in range(10, 10+Cardlen):
                        Card16H = Card16H + '%02X' % (data[num])
                    Cardno = data[10]   #转10进制卡号
                    Cardno = Cardno + (data[11] * 256)
                    Cardno = Cardno + (data[12] * 65536)
                    Cardno = Cardno + (data[13] * 16777216)
                    CardnoStr = '%010d' % Cardno

                    SerialNum = ''  # 设备硬件序列号
                    for num in range(10+Cardlen, len(data)):
                        SerialNum = SerialNum + '%02X' % (data[num])
                    if (data[0] == eval('0xC1')):
                        print('数据解析:IC读卡器刷卡数据,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo +",卡号长度:"+"%d" %(Cardlen)+ ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum+"\n")
                    else:
                        print('数据解析:IC卡离开读卡器,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo +",卡号长度:"+"%d" %(Cardlen)+ ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum + "\n")

                    RespByte=GetResponseData(2)     #根据不同情况生成要回应指令码
                    self.request.sendall(RespByte)  #发送回应指令码
                    SendData = 'Send Data to %s:%s' % (self.client_address) + " :"
                    for num in range(0, len(RespByte)):
                        SendData = SendData + '%02X ' % (RespByte[num])
                    print(SendData+"\n")

                elif (data[0] == eval('0xD1') or data[0] == eval('0xDF')):   # 接收ID读卡器上传的读卡号数据、ID卡离开读卡器数据
                    FunCode = '%02X' % (data[0])
                    DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])  # 设备IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 机号
                    FrameNo = '%d' % (data[7] + data[8] * 256)  # 数据包序号
                    Card16H = '%02X%02X%02X%02X%02X' % (data[9],data[10], data[11], data[12], data[13])  # 16进制卡号
                    Cardno = data[9]       #转10进制卡事情
                    Cardno = Cardno + (data[10] * 256)
                    Cardno = Cardno + (data[11] * 65536)
                    Cardno = Cardno + (data[12] * 16777216)
                    CardnoStr = '%010d' % Cardno
                    SerialNum = ''  # 设备硬件序列号
                    for num in range(14, len(data)):
                        SerialNum = SerialNum + '%02X' % (data[num])

                    if (data[0] == eval('0xD1')):
                        print('数据解析:ID读卡器刷卡数据,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo + ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum + "\n")
                    else:
                        print('数据解析:ID卡离开读卡器,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo + ",16进制卡号:" + Card16H + " 转10进制卡号:" + CardnoStr + ",硬件序列号:" + SerialNum + "\n")

                    RespByte = GetResponseData(2)  # 根据不同情况生成要回应指令码
                    self.request.sendall(RespByte)  # 发送回应指令码
                    SendData = 'Send Data to %s:%s' % (self.client_address) + " :"
                    for num in range(0, len(RespByte)):
                        SendData = SendData + '%02X ' % (RespByte[num])
                    print(SendData + "\n")

                elif (data[0] == eval('0xF3')):  # 接收到设备的心跳数据包,设备心跳间隔可根据协议自行设置
                    FunCode = '%02X' % (data[0])
                    DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])  # 设备IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 机号
                    FrameNo = '%d' % (data[7] + data[8] * 256)  # 数据包序号
                    heartbeattype='%02X' % (data[9])
                    outleng='%d' % (data[10])
                    switchon='%02X' % (data[11])
                    inputinf='%02X' % (data[12])
                    rand='%02X%02X%02X%02X' % (data[13], data[14], data[15], data[16])
                    SerialNum = ''
                    for num in range(17, len(data)):
                        SerialNum = SerialNum + '%02X' % (data[num])
                    print('接收数据解析:设备心跳包,设备IP:' + DEvIp + ',机号:' + DevNo + ",数据包号:" + FrameNo + ",心跳类型:" + heartbeattype + ",长度:" + outleng+ ",继电器状态:" + switchon + ",输入接口状态:" + inputinf + ",随机校验码:" + rand  + ",硬件序列号:" + SerialNum + "\n")

def GetResponseData(respcode):      # 生成不同的回应数据
    sdata=bytearray()
    if (respcode==0):               # 生成蜂鸣响声的回应数据
        sdata.append(eval('0x96'))  # 蜂鸣响声的指令码
        sdata.append(eval('0x00'))  # 机号低
        sdata.append(eval('0x00'))  # 机号高,0000表示任意机号
        sdata.append(eval('0x01'))  # 蜂鸣响声代码,取值范围0-12

    elif(respcode==1):              # 生成显示文字+蜂鸣响声的 回应数据
        DispStr = "本次刷卡成功,感谢您的使用,再见!            "
        DispByte = bytes(DispStr, encoding='gbk')    # 将要显示的文字转bytes
        DispByte = DispByte[0:34]                    # 两行屏可以显示34个字符
        CommByte=bytes([eval('0x5A'), 0, 0, 2, 30])  # 5A是指令码+2字节机号+1字节蜂鸣代码+1字节显示时长
        sdata = CommByte + DispByte                  # 加入显示文字的ASC码

    elif (respcode == 2):           # 生成显示文字+蜂鸣响声的+继电器开关+TTS中文语音的 回应数据
        DispStr = "本次刷卡成功,感谢您的使用,再见!            "
        DispByte = bytes(DispStr, encoding='gbk')   # 将要显示的文字转bytes
        DispByte = DispByte[0:34]                   # 两行屏可以显示34个字符

        SpkStr = '[v1]欢迎您使用我们的网络读卡器,谢谢!'     # 要播报的TTS语音,[v10]表示音量,取值0-16,可放置字符串的任意地方,一次最多126个字节
        Spkb = bytes(SpkStr, encoding='gbk')            # 将要播报的TTS语音转bytes,
        Spkl = len(Spkb)  # TTS语音长度

        sufb = bytes([eval('0x55'), eval('0xaa'), eval('0x66'), eval('0x99')])      # 固定的抗干扰后缀
        comb = bytes([eval('0x5C'), 0, 0, 1, eval('0xF0'), 20, 0, 20, 0, 34,Spkl])  # 5C是指令码+2字节机号+1字节蜂鸣代码+1字节继电器代码+2字节继电器延时+1字节显示时长+1字节显示起始位+1字节显示长度+1语音长度
        sdata = comb + DispByte + Spkb + sufb

    elif (respcode == 3):  # 生成开启继电器开关的 回应数据
        sdata.append(eval('0x78'))  # 蜂鸣响声的指令码
        sdata.append(eval('0x00'))  # 机号低
        sdata.append(eval('0x00'))  # 机号高,0000表示任意机号
        sdata.append(eval('0xF0'))  # 继电器代码 F0表示全部继电器、F1表示1号继电器 、F2表示2号继电器......
        sdata.append(eval('0x2c'))  # 继电器开启延时低位
        sdata.append(eval('0x01'))  # 继电器开启延时高位,FFFF表示继电器一直开启
    return sdata


if __name__ == "__main__":
    IpList = []
    if sys.platform == 'linux' or sys.platform == 'mac':  # linux、mac系统获取电脑所有网卡IP
        ips = [ip.split('/')[0] for ip in os.popen("ip addr | grep 'inet '|awk '{print $2}'").readlines()]
        for i in ips:
            IpList.append(i)
            print('%d   ' % (len(IpList)) + i)
    else:
        addrs = socket.getaddrinfo(socket.gethostname(), None)  # windows获取电脑所有网卡IP
        for item in addrs:
            if ':' not in item[4][0]:
                IpList.append(item[4][0])
                print('%d   ' % (len(IpList)) + item[4][0])

    Bindip = IpList[0]          # 如有多张网卡,可选择绑定不同的网卡
    address = ('', 39169)       # 未指定绑定网卡,可侦听本机所有网卡信息,读卡器出厂默认39169通讯端口

    with socketserver.ThreadingTCPServer(address, Server) as server:
        try:
            server.serve_forever()
        except Exception as e:
            print(e)
            pass
    pass
相关推荐
飞翔的佩奇39 分钟前
【完整源码+数据集+部署教程】表盘指针检测系统源码和数据集:改进yolo11-CA-HSFPN
python·yolo·计算机视觉·数据集·yolo11·表盘指针检测
larance1 小时前
SQLAlchemy 的异步操作来批量保存对象列表
数据库·python
搏博2 小时前
基于Python3.10.6与jieba库的中文分词模型接口在Windows Server 2022上的实现与部署教程
windows·python·自然语言处理·flask·中文分词
lxmyzzs3 小时前
pyqt5无法显示opencv绘制文本和掩码信息
python·qt·opencv
海绵不是宝宝8173 小时前
连接远程服务器上的 jupyter notebook,解放本地电脑
服务器·jupyter·github
三坛海会大神5553 小时前
计算机网络参考模型与子网划分
网络·计算机网络
云卓SKYDROID3 小时前
无人机激光测距技术应用与挑战
网络·无人机·吊舱·高科技·云卓科技
萧鼎4 小时前
Python pyzmq 库详解:从入门到高性能分布式通信
开发语言·分布式·python
yujkss5 小时前
Python脚本每天爬取微博热搜-终版
开发语言·python
yzx9910135 小时前
小程序开发APP
开发语言·人工智能·python·yolo