我对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 useLogServer.allow_reuse_address = True / False,不会更改任何内容。
发布于 2021-01-25 02:04:22
我在Python3.7.2中使用(非线程) socketserver.TCPServer实例时也遇到了同样的问题。(我在opensuse上使用anaconda,以防万一)
我的解决方案是:
在服务器初始化期间,我将__init__函数的第三个参数设置为false:
__init__标志设置为True,只有在设置了此标志之后,才会调用.server_bind()和.server_activate()函数。我认为重要的是在绑定和激活服务器之前设置bind_and_activate标志,因为如果TCPServer初始化期间的bind_and_activate参数为真或未设置,则TCPServer.__init__()将同时调用server_bind()和server_activate()函数。在这种情况下,我无法更改.allow_reuse_address标志的值-我可以从print()调用中看到它。
(请注意,下面的代码不起作用,因为其中缺少请求处理程序定义。我也使用超时,但这与问题无关)
def set_up_server_for_one_request(host, port, reqHandler, timeout = 600):
''' set up a server for one request. there is timeout as well.
'''
with socketserver.TCPServer((host, port), reqHandler, \
bind_and_activate= False) as serverInstance:
print('reuse adress attribute before flag setting: ',\
serverInstance.socket.getsockopt(socket.SOL_SOCKET,\
socket.SO_REUSEADDR))#print flagVal before setting
serverInstance.allow_reuse_address = True
print('reuse adress attribute after flag setting: ',\
serverInstance.socket.getsockopt(socket.SOL_SOCKET, \
socket.SO_REUSEADDR)) #print flagVal after setting
print('server adress: ', serverInstance. server_address)
serverInstance.server_bind()
serverInstance.server_activate()
serverInstance.timeout = timeout #set server's timeout
serverInstance.handle_request()
print('server finished, and exits')
if __name__ == '__main__':
set_up_server_for_one_request(host = 'localhost', port = 9998,\
reqHandler = My_EchoRH, timeout = 20)https://stackoverflow.com/questions/38324405
复制相似问题