SocketServer在退出

时间:2016-07-12 09:05:11

标签: python socketserver

我在Python(2.7)socketserver中遇到以下问题:

import wx
import socket
from SocketServer import BaseRequestHandler, ThreadingTCPServer
from threading import Thread
from wx.lib.pubsub import pub
from GUI import GUI

class LogHandler(BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        wx.CallAfter(pub.sendMessage, 'logmsg', msg=data)
        self.request.close()

class MyTestGUI(GUI):
    def __init__(self):
        super(MyTestGUI, self).__init__(None)
        pub.subscribe(self.AppendLog, 'logmsg')

        self.LogServer = ThreadingTCPServer(('', 10010), LogHandler)
        self.LogServer.allow_reuse_address = True
        self.thd = Thread(target=self.LogServer.serve_forever)
        self.thd.daemon = True
        self.thd.start()

    def AppendLog(self, msg):
        # Append the mesage
        print(msg)

    def AppClose(self, event):
        self.LogServer.shutdown()
        self.LogServer.server_close()
        exit()

if __name__ == '__main__':
    app = wx.App()
    frame = MyTestGUI()
    frame.Show(True)
    app.MainLoop()

此服务器应该从设备接收消息(在发送消息时关闭套接字)。在第一次运行时代码工作正常,但重启后我得到以下异常:

    self.LogServer = ThreadingTCPServer(('', 10010), LogHandler)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 420, in __init__
    self.server_bind()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 434, in server_bind
    self.socket.bind(self.server_address)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 48] Address already in use

LogServer.allow_reuse_address = True / False,不会更改任何内容。

1 个答案:

答案 0 :(得分:0)

我在带有(非线程)socketserver.TCPServer 实例的 Python 3.7.2 中遇到了同样的问题。 (我在 opensuse 上使用 anaconda,以防万一)

我的解决方案:

  1. 在服务器初始化期间我设置了 __init__ 函数的第三个参数 假:bind_and_activate = False
  2. 初始化后,我将 .allow_reuse_address 标志设置为 True,只有在设置此标志后才会调用 .server_bind().server_activate() funs。

我认为重要的是在 bindig 和激活服务器之前设置 bind_and_activate 标志,因为如果 TCPServer 初始化期间的 bind_and_activate 参数为 True 或未设置,那么 {{1} } 调用 TCPServer.__init__()server_bind() 函数。在这种情况下,我无法更改 server_activate() 标志的值 - 我可以从 .allow_reuse_address 调用中看到它。

(请注意,下面的代码不起作用,因为其中缺少请求处理程序定义。我也使用超时,但这与问题无关)

print()