一天后扭曲的服务器崩溃

时间:2016-03-21 03:26:52

标签: python twisted

我编写了一个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秒向服务器发送一条消息

2 个答案:

答案 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()

我认为没关系,但是,对于连接,经常打开和关闭它,使用连接池是否更好?