我在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,不会更改任何内容。
答案 0 :(得分:0)
我在带有(非线程)socketserver.TCPServer
实例的 Python 3.7.2 中遇到了同样的问题。 (我在 opensuse 上使用 anaconda,以防万一)
我的解决方案:
__init__
函数的第三个参数
假:bind_and_activate = False
。.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()