我编写了一个Udp扭曲服务器并使用以下命令运行它:
nohup python Udpserver2.py &
起初进展顺利,但是它带来了一个错误并在1天后崩溃了。 nohup.out
中的错误信息为:
Unhandled Error
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/log.py", line 84, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 597, in _doReadOrWrite
why = selectable.doRead()
--- <exception caught here> ---
File "/usr/lib64/python2.7/site-packages/Twisted-15.4.0-py2.7-linux-x86_64.egg/twisted/internet/udp.py", line 248, in doRead
self.protocol.datagramReceived(data, addr)
File "UdpServer2.py", line 91, in datagramReceived
self.device_echo(data, str(host), int(port))
File "UdpServer2.py", line 19, in device_echo
cur.execute(sql)
File "/usr/lib64/python2.7/site-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib64/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away')
我的python代码UdpServer2.py
的结构如下:
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import MySQLdb as mdb
conn = mdb.connect(host='localhost', user='root', passwd='123456', db='kj')
class KjEcho(DatagramProtocol):
def device_echo(self, msg, host, port):
device_no = msg[1:7]
sql = "select did from device where device_no='%s'" % (device_no)
cur = conn.cursor(mdb.cursors.DictCursor)
cur.execute(sql) #line 19 here
if 0 == cur.rowcount:
...
else:
...
cur.close()
def startProtocol(self):
print 'kj_udp_server starting...'
def datagramReceived(self, data, (host, port)):
print "receive msg"
if(18 != len(data)):
print 'len err'
return
if('0x86' != hex(ord(data[0]))):
print '0x86 err'
return
if(0 == ord(data[15])):
print 'from device'
self.device_echo(data, str(host), int(port)) #line 91 here
else:
print 'from mobile'
self.mobile_echo(data, str(host), int(port))
reactor.listenUDP(6000, KjEcho())
reactor.run()
第91行和第19行是上述原因,如何解决,谢谢。
注意:有很多机器,每台机器每20秒向服务器发送一条消息
答案 0 :(得分:0)
您无法在未指定的时间段内继续使用mysql连接(或任何套接字),特别是如果没有数据流过它。因此,不要只重新使用一个连接来获取光标,而是关闭与光标的连接并在需要时再次打开它。
所以从本质上讲,你想要在这一行前加上
cur = conn.cursor(mdb.cursors.DictCursor)
用一个设置conn
,然后附加以下
cur.close()
关闭conn
,最有可能是conn.close()
。
答案 1 :(得分:0)
非常感谢,Mai和Tymoteusz Paul
class KjEcho(DatagramProtocol):
def device_echo(self, msg, host, port):
device_no = msg[1:7]
sql = "select did from device where device_no='%s'" % (device_no)
conn = mdb.connect(host='localhost', user='root', passwd='123456', db='kj')
cur = conn.cursor(mdb.cursors.DictCursor)
cur.execute(sql)
if 0 == cur.rowcount:
...
else:
...
cur.close()
conn.close()
我认为没关系,但是,对于连接,经常打开和关闭它,使用连接池是否更好?