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。