Python socketserver,如何获取自己的TCP端口号

3

我需要使用socketserver构建一个tcp服务器。根据他们的文档,我需要继承类TCPServer,并将其传递给BaseRequestHandler类的子类,其中我重写方法handle()。

现在我需要在不同的端口上构建两个服务器,是否有一种方法可以在handle()函数中获取我的端口号?(否则我就必须设置两个几乎相同的处理程序类,这不是我想要的)

2个回答

1
不要在handle()方法中实现,从这个https://docs.python.org/2/library/socketserver.html#socketserver-tcpserver-example中传递端口号:
#!/usr/bin/env python

import SocketServer, argparse

class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        # self.server.server_address is a tuple (IP, port) the server is listening on                                                       
        (host, port) = self.server.server_address
        print 'port # is: {}'.format(port)
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--port', required=True, help='the TCP port to listen on')
    args = parser.parse_args()
    HOST, PORT = "localhost", int(args.port)

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()

在这个例子中,当你使用-p命令行开关启动程序时,你必须提供端口号作为参数。

假设这两个句柄函数几乎完全执行相同的操作,除非端口是9999,则打印9999,如果端口是9998,则打印9998。这是否意味着我必须设置两个处理程序类? - Rusheng Zhang
请参考上面的更新示例。我可以使用相同的代码启动2个侦听器(一个在端口9998上,另一个在端口9999上),方法如下:./sockserv.py -p 9998 &(运行第一个服务器,放到后台)然后这样做:./sockserv.py -p 9999 &(另一个服务器,不同的端口号,放到后台)。 - davejagoda
谢谢,但我的问题是如何将端口号传递给函数handle(),因为我的两个handle函数几乎相同,但基于端口号不同。 - Rusheng Zhang
我又做了一个改变 - 处理程序现在会打印出它所传递的端口。请试一下。 - davejagoda
太好了!我担心我们之间有误解,很高兴我们解决了这个问题。 - davejagoda

0

我刚刚发现了一个可能可行的解决方案,但它仍然不够好,因为我仍然需要更改代码中的两个端口才能使其正常工作:

import socket
import threading
import SocketServer


class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    port = None
    def handle(self):
        while True:
            data = self.request.recv(1024)
            if not data:
                break
        print self.port,data

class ThreadedTCPRequestHandler1(ThreadedTCPRequestHandler):
    port = 9999

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass        

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler1)
    ip, port = server.server_address

    server_thread = threading.Thread(target=server.serve_forever)

    server_thread.daemon = True
    server_thread.start()
    #print "Server loop running in thread:", server_thread.name
    try:
        while True:
            continue
    finally:
        print 'quitting server'
        server.shutdown()
        server.server_close()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接