Python Socket Udp云消费机源代码

#python通过缩进来表示代码块,不可以随意更改每行前面的空白,否则程序会运行错误!!!如果缩进不一致,会报错: IndentationError

#!/usr/bin/env python

# -*- coding: utf-8 -*-

#QQ:954486673

#微信:13822155058

#淘宝:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.14.2cc25124mfeHaQ&id=17021194999

 

import socket

import time

#接收到设备信息后,服务器向设备的反馈信息---------------------------------------------------------

def SendInfToIp(SendInfStr,addr):

    sdata=bytes(SendInfStr, encoding='gbk')  #将要发送的信息转为bytes

    s.sendto(sdata,addr)  

    message = 'SendData To %s:%s' % (addr, sdata)

    print(message+"\n")                   

   

#获取电脑系统日期时间----------------------------------------------------------------------------------

def get_time():

    st = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

    st=st[0:16]

    return st

 

#判断字符串是否为有效的日期时间-------------------------------------------------------------------

def isVaildDate(datestr):

    try:

        datetime.datetime.strptime(datestr,'%Y-%m-%d %H:%M:%S')

        return 1

    except:

        return 0

 

#主程序-------------------------------------------------------------------------------------

addrs = socket.getaddrinfo(socket.gethostname(),None)   #获取本电脑所有网卡IP

IpList=[]

for item in addrs:   

    if ':' not in item[4][0]:

        IpList.append(item[4][0])

        print('%d   '%(len(IpList)) + item[4][0])

 

BUFSIZE = 1024

Bindip=IpList[1]  #如果电脑有多个网卡IP,可以选择绑定不同的IP

Bindprot=39192

 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

s.bind((Bindip, Bindprot))

print('\n系统绑定IP:'+Bindip+':%d'% (Bindprot)+'\n')

print('发送搜索在线设备的广播指令')

sdata=b'000'           

s.sendto(sdata,('255.255.255.255',Bindprot))   #发送搜索同网段内所有在线设备的广播指令

print('Send To IP:255.255.255.255:'+str(Bindprot))

print('Send Data:000\n')

 

LastBuf=''              #保存最后接收到的信息,用于比较是否重复接收的信息

 

while True:

    data, addr = s.recvfrom(BUFSIZE)

    message = 'Received from %s:%s \n' % (addr, data)

    print(message)

   

    GetInf=str(data, encoding = "gbk")   

    FieldsList=GetInf.split(',')

   

    if(LastBuf==GetInf and len(FieldsList)>1):             #对比当前接收到的数据是否重发的数据包

        SendInfStr="001,"+FieldsList[1]                    #是已解析过的相同数据,确定接收,不用再分析处理

        SendInfToIp(SendInfStr,addr)

    else:

        LastBuf=GetInf                                     #将接收到的信息可存,用做下次接收到数据后

       

        if(FieldsList[0]=='100'):                          #设备接收到000搜索指令后返回的设备信息

            if(len(FieldsList)<9):

                DevBufferIpAddrStr= FieldsList[1]          #终端IP

                DevBufferMaskStr= FieldsList[2]            #掩码

                DevBufferGatewayStr= FieldsList[3]         #网关

                DevBufferRemoteAddrStr= FieldsList[4]      #远程服务器IP

                DevBufferPort= FieldsList[5]               #端口

                DevBufferNumberDecStr= FieldsList[6]       #设备序号

            else:

                DevBufferIpAddrStr= FieldsList[1]          #终端IP

                DevBufferMaskStr= FieldsList[2]            #掩码

                DevBufferGatewayStr= FieldsList[3]         #网关

                DevBufferGatewayStrMAC= FieldsList[4]      #网关MAC

                DevBufferRemoteAddrStr= FieldsList[5]      #远程服务器IP

                DevBufferRemoteAddrMACStr= FieldsList[6]   #远程服务器IPMAC

                DevBufferMACSearchStr= FieldsList[7]       #MAC搜索标识

                DevBufferPort= FieldsList[8]               #端口

                DevBufferNumberDecStr= FieldsList[9]       #设备模块序号

                if(len(FieldsList)>10):

                    DevBufferSerialNumStr= FieldsList[10]  #设备唯一硬件序号

                   

        elif(FieldsList[0]=='101'):                        #接收到设备的开机信号

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferDatetimeStr = FieldsList[5]       #设备日期时间

                if(len(FieldsList)>6):                     #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[6]

                                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

                     

                GetDT=DevBufferDatetimeStr[0:16]

                SysDT= get_time()

 

                if (GetDT!=SysDT):                        #设备时钟与系统不符,更新设备时间

                    SendInfStr="003," + DevBufferMachinStr +"," + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())   

                    SendInfToIp(SendInfStr,addr)

                   

        elif(FieldsList[0]=='102'):                        #接收到消费机的刷卡信息

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCardidStr = FieldsList[5]         #卡号

                if(len(FieldsList)>6):                     #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[6]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

                     

                #可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息

                     

                #用009指令 将业务处理结果发送到设备

                #设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制

                     

                SendInfStr="009,"+ DevBufferMachinStr + ",卡号:" + DevBufferCardidStr  + "\\nn姓名:张三丰\\n余额:888.88\\n状态:卡可正常使用\\n,20,1,0"

                SendInfToIp(SendInfStr,addr)

               

        elif(FieldsList[0]=='103'):                        #接收到 输入消费金额后刷卡、消费机定额消费、消费机计次消费 的上传信息

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCardidStr = FieldsList[5]         #卡号

                DevBufferUseMoneryStr= FieldsList[6]       #消费金额

                DevBufferUseTimeStr= FieldsList[7]         #消费时间

                if(len(FieldsList)>8):                     #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[8]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

                     

                #可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息

                     

                #用006指令返回本次消费失败

                #用008指令返回本次消费成功

                #设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制

                     

                #SendInfStr="006," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + "姓名:张三丰  \\n余额:168.88 \\n状态:此卡已挂失 \\n ,20,0,6"

                SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + DevBufferUseMoneryStr + "," + "姓名:张三丰 {123.45}\\n,20,0,1"

                SendInfToIp(SendInfStr,addr)

               

        elif(FieldsList[0]=='104'):                        #接收到 计次消费模式下,终端刷卡后设备向电脑发送此信息

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCardidStr = FieldsList[5]         #卡号

                DevBufferUseTimeStr= FieldsList[6]         #消费时间

                if(len(FieldsList)>7):                     #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[7]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

                     

                #可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息

                     

                #用006指令返回本次消费失败

                #用008指令返回本次消费成功

                #设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制

                     

                SendInfStr="006," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + "姓名:张三丰  \\n余额:168.88 \\n状态:此卡已挂失\\n ,20,0,6"

                #SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCardidStr + ",0.00," + "姓名:张三丰 {123.45}\\n,20,0,1"

                SendInfToIp(SendInfStr,addr)                

               

        elif(FieldsList[0]=='105'):                        #接收到脱网时 白名单卡 记账消费记录

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCardidStr = FieldsList[5]         #卡号

                DevBufferUseMoneryStr= FieldsList[6]       #消费金额

                DevBufferUseTimeStr= FieldsList[7]         #消费时间

                DevBufferStaryStr= FieldsList[8]           #消费方式  0扣费 1计次

                DevBufferRecordAddStr= FieldsList[9]       #记录地址标识

                DevBufferAllNoStr= FieldsList[10]          #总计录数

                if(len(FieldsList)>11):                    #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[11]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)              

               

                if(isVaildDate(DevBufferUseTimeStr)==0):   #判断消费时间是否正确

                    DevBufferUseTimeStr="9999-99-99 99:99:99"   #如果消费时间不正确,需更为 9999-99-99 99:99:99 才能将此条非法记录删除

                #时间正确说明是条有效记录,可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息 

               

                #清除设备内当前这条已上传的记录,驱动设备继续上传剩下的记录

                SendInfStr="011," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + DevBufferUseMoneryStr + "," + DevBufferUseTimeStr + "," + DevBufferRecordAddStr

                SendInfToIp(SendInfStr,addr)

               

        elif(FieldsList[0]=='106'):                        #接收到设备的按键信息

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferUseTimeStr= FieldsList[5]         #按键信息

                if(len(FieldsList)>6):                     #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[6]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

                     

                #可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息

               

        elif(FieldsList[0]=='108'):                        #接收到设备在订取餐模式下刷卡取餐的信息

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCardidStr = FieldsList[5]         #卡号

                if(len(FieldsList)>6):                     #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[6]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

                     

                #可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息

                     

                #用013指令回复本次取餐结果,正式系统开发时要有重发机制

                #设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制

                SendInfStr="013," + DevBufferMachinStr + ",卡号:" + DevBufferCardidStr + "\\n姓名:张三丰  \\n状态:水煮肉片套餐\\n份数:1  余额:{123.8}\\n,20,0,27"

                SendInfToIp(SendInfStr,addr)

               

        elif(FieldsList[0]=='109'):                        #设备接收到服务器发送信息的反馈信息,服务器端发送完006、008、009、103指令后,如立即接收到此信息表明设备已经接收到

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCommandStr = FieldsList[5]        #指令码

               

        elif(FieldsList[0]=='150'):                        #接收到实时考勤门禁机的刷卡信息

                DevRecFramesStr = FieldsList[1]            #包序列号

                DevBufferIpAddrStr = FieldsList[2]         #终端IP

                DevBufferRemoteAddrStr = FieldsList[3]     #远程电脑指机IP

                DevBufferMachinStr = FieldsList[4]         #机号

                DevBufferCardidStr = FieldsList[5]         #卡号

                DevBufferReaderStr= FieldsList[6]          #读头号

                DevBufferDoorNoStr= FieldsList[7]          #门或继电器号

                DevBufferDelayStr= FieldsList[8]           #门磁未关秒数,0表示已关

                DevBufferPasswPropStr= FieldsList[9]       #密码属性(0密码无效,1刷卡后按密码,2补签密码,3开门密码,4防迫胁密码)

                DevBufferPassWStr= FieldsList[10]          #密码(最多8位数字)

                DevBufferUseTimeStr= FieldsList[11]        #刷卡时间

                if(len(FieldsList)>12):                    #2018年以后的设备有唯一硬件序号

                    DevBufferSerialNumStr=FieldsList[12]

                     

                SendInfStr="001,"+DevRecFramesStr          #确定接收到信息,否则设备会连续发送三次

                SendInfToIp(SendInfStr,addr)         

               

                #可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息

                #用050指令返回开门成功

                #用051指令返回开门失败,正式系统开发时要有重发机制

               

                #SendInfStr="051," + DevBufferMachinStr + "," + DevBufferCardidStr + ",卡号:" + DevBufferCardidStr + "\\n姓名:张三丰  \\n状态:无效卡\\n,20,1,3"

                SendInfStr="050," + DevBufferMachinStr + "," + DevBufferCardidStr + ",卡号:" + DevBufferCardidStr + "\\n姓名:张三丰  \\n状态:欢迎关临\\n,20,1,0," + DevBufferReaderStr + "," + DevBufferDoorNoStr + ",5,20"

                SendInfToIp(SendInfStr,addr)

               

        #更多的字段说明及回复方式,请仔细查看设备的通讯协议说明...

 

 

猜你喜欢

转载自blog.csdn.net/zhangjin7422/article/details/110110290