在Twisted中使用多线程服务器时地址已被占用

1 投票
1 回答
821 浏览
提问于 2025-04-16 08:07

我正在用Python和Twisted写一个多线程的服务器。每当客户端向服务器请求东西时,我会用callInThread(self.task)来创建一个新线程来运行task()。当客户端一个接一个地发送请求(都是通过53号端口)时,一切都正常。但是当同时有多个请求时,就出现了这样的错误:

文件“”,第1行,在bind中 socket.error: [Errno 98] 地址已在使用中

这是不是说明我的线程有问题?是不是说一次只能有一个线程使用这个端口?如果是这样的话,我该如何实现服务器的多线程呢?非常感谢!

class BaseThreadedUDPServer(DatagramProtocol):
    def datagramReceived(self, datagram, (host, port)):
        print "received %r from %s:%d" % (datagram, host, port)
        reactor.callInThread(self.task)

    def task(a):
        print "waiting on port:", csport
        while 1:
            ## RCV QUERY ##
            query, addr = csSocket.recvfrom(csbuf)
            ## GET ANS ##
            ans = socket.gethostbyname(query)
            ## SEND ANS ##
            scSocket.sendto(ans, scaddr)

def main():
    print "main"
    reactor.listenUDP(53, BaseThreadedUDPServer())
    reactor.run()

1 个回答

2

你其实不需要用线程。这种做法会出很多问题。Twisted已经为你调用了recv,而它的结果会传给datagramReceived。你自己不要再调用一次。你不需要线程。

不过,这个问题可能和你的情况没什么关系。53是默认的DNS端口;你遇到的问题是,可能是另一个服务器,通常是DNS服务器,已经在你的电脑上运行了。试着把53改成其他的数字。

不过我不太确定;下次请提供完整的错误追踪信息。那个追踪信息的第一行显然不是你粘贴的例子中的内容,因为第一行除了一个'class'声明外什么都没有。而且,由于这段代码缩进不对,导致出现SyntaxError错误,显然和你运行的代码不完全一样。

假设你确实在处理DNS,Twisted有自己的DNS服务器;你应该使用twisted.names,而不是自己去实现DNS数据包的解析。

撰写回答