twistd脚本编写UDP服务

twistd的twisted框架提供的一个工具,可以帮助开发者编写守护进程。

网上有一个完整的TCP服务的示例

https://www.cnblogs.com/suke99/p/5359292.html

相关的源代码在:https://github.com/jdavisp3/twisted-intro/blob/master/twisted-server-3/fastpoetry.py#L1

我这边给出一个UDP的:

from twisted.internet import epollreactor
try:
    epollreactor.install()
except Exception, e:
    print "epoll install failed:%s" % str(e)
from twisted.application import internet, service
from twisted.internet.protocol import ServerFactory,DatagramProtocol
from twisted.python import log
from twisted.enterprise import adbapi

import pymysql
from pymysql import cursors

import binascii
#import IPy
import struct
import datetime
import logging
from logging.handlers import RotatingFileHandler

def printBin(data):
    s1=binascii.b2a_hex(data).decode('utf-8')
    #print s1
    #myhex=[]
    #for x in bytes(data):
    #    myhex.append(hex(ord(x)))
    #print " ".join(myhex)
    return s1

#打印日志信息
def printLog(strTitle,strMsg):
    now=datetime.datetime.now()
    strNow=now.strftime("%Y-%m-%d %H:%M:%S")
    print "%s [-] %s->%s" %(strNow,strTitle,strMsg)
    


#分析H3C FLOW日志版本3,并存入数据库
def getDataV3(cursor,item):
    data,logger=item
    #int2ip = lambda x: '.'.join([str(x/(256**i)%256) for i in range(3,-1,-1)])
    if len(data)<44:
        logger.error("data too short!")
        logger.error(printBin(data))
        return None
    #NAT转换前的源IP地址
    mydata=data[20:42]
    SourceIP,SrcNatIP,DestIP,DestNatIP,SrcPort,SrcNatPort,DestPort=struct.unpack( "!LLLLHHH" ,mydata)
    #strTitle="natLog"
    #strSourceIP=int2ip(SourceIP)
    #strSrcNatIP=int2ip(SrcNatIP)
    #strDestIP=int2ip(DestIP)
    #strMsg="%s(%s:%d)->%s:%d" %(strSourceIP,strSrcNatIP,SrcNatPort,strDestIP,DestPort)
    #printLog(strTitle,strMsg)
    #print strSourceIP
    #print strMsg
    #logger.info(strMsg)
    try:
        cursor.execute("insert into nat_log(SourceIP,SrcNatIP,DestIP,SrcNatPort,DestPort) values(%s,%s,%s,%s,%s)",(SourceIP,SrcNatIP,DestIP,SrcNatPort,DestPort))
    except Exception, e:
        #traceback.print_exc()
        logger.error(str(e),exc_info = True)
        logger.error(printBin(data))

def handle_error(self, error, item):
    datagram,logger=item
    s1=binascii.b2a_hex(datagram).decode('utf-8')
    logger.error(error+":"+s1)
    
class MySyslog(DatagramProtocol):
    def __init__(self,service):
        self.service=service
    
    def stopProtocol(self):
        print "stopProtocol"
    
    def startProtocol(self):
        print "startProtocol"
    
    def makeConnection(self,s):
        print "makeConnection"
        
    def syslogPkt(self,data,host):
        #print host
        #FromHost=host
        #print data
        #printBin(data)
        pass
        #print Message
    def datagramReceived(self, datagram, (host, port)):
        dbpool=self.service.dbpool
        logger=self.service.logger
        #int2ip=self.service.int2ip
        try:
            defer = dbpool.runInteraction(getDataV3, (datagram,logger))
            defer.addErrback(handle_error, (datagram,logger))
        except Exception ,ex:
            logger.error(str(ex),exc_info = True)

class MyFactory(ServerFactory):

    protocol = MySyslog

    def __init__(self, service):
        self.service = service
    
    def makeConnection(self,s):
        print "makeConnection"
        print type(s)
        print s

class MyService(service.Service):

    def __init__(self,):
        self.dbpool=None
        self.logger=None
        self._base_path="/python/nat_log/"
        #self.int2ip = lambda x: '.'.join([str(x/(256**i)%256) for i in range(3,-1,-1)])
    def startService(self):
        print "startServer"
        dbparmas = {
            'host': '2.2.2.2',
            'user': 'yourname',
            'password': 'yourpass',
            'database': 'nat',
            'charset': 'utf8',
            'cursorclass': cursors.DictCursor
            }
        self.dbpool = adbapi.ConnectionPool('pymysql', **dbparmas)
        self.logger = logging.getLogger('newNatLog')
        self.logger.setLevel(level = logging.INFO)

        handler = RotatingFileHandler(self._base_path+"log.txt",maxBytes=409600,backupCount=5)
        handler.setLevel(logging.INFO)
        formatter = logging.Formatter('%(asctime)s - %(funcName)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)

        console = logging.StreamHandler()
        console.setLevel(logging.WARNING)
        console.setFormatter(formatter)
        self.logger.addHandler(console)
            
port = 5140
top_service = service.MultiService()
myservice=MyService()
myservice.setServiceParent(top_service)
mysyslog = MySyslog(myservice)
udp_service=internet.UDPServer(port,mysyslog)
udp_service.setServiceParent(top_service)
application = service.Application("natlog")
top_service.setServiceParent(application)

service接口实际上只起到初始化的作用。使用twistd的时候不要使用全局变量,把这种全局使用的变量都放进service接口里面,用的时候从这个service里面引用即可,比如我要用dbpool,那这个就在自己定义的MyService里面定义,并在MyService的startService里面初始化。在MySyslog的协议代码里,把service的实例myservice做为初始化参数传入,这样在datagramReceived函数里面就可以引用它了dbpool=self.service.dbpool。这里面我用的log是python自带的,其实最好使用twisted的log。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值