简体   繁体   English

Python的SocketServer中的TCPServer + BaseRequestHandler是否在每次调用handle()后关闭套接字?

[英]Does the TCPServer + BaseRequestHandler in Python's SocketServer close the socket after each call to handle()?

I'm writing a client/server application in Python and I'm finding it necessary to get a new connection to the server for each request from the client. 我正在用Python编写客户端/服务器应用程序,我发现有必要为客户端的每个请求获取与服务器的新连接。 My server is just inheriting from TCPServer and I'm inheriting from BaseRequestHandler to do my processing. 我的服务器只是继承自TCPServer,我继承BaseRequestHandler来进行处理。 I'm not calling self.request.close() anywhere in the handler, but somehow the server seems to be hanging up on my client. 我不是在处理程序中的任何地方调用self.request.close(),但不知何故服务器似乎挂在我的客户端上。 What's up? 这是怎么回事?

Okay, I read the code (on my Mac, SocketServer.py is at /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/). 好的,我读了代码(在我的Mac上,SocketServer.py位于/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/)。

Indeed, TCPServer is closing the connection. 实际上,TCPServer正在关闭连接。 In BaseServer.handle_request , process_request is called, which calls close_request . BaseServer.handle_request ,调用process_request ,调用close_request In the TCPServer class, close_request calls self.request.close() , and self.request is just the socket used to handle the request. 在TCPServer类中, close_request调用self.request.close() ,而self.request只是用于处理请求的套接字。

So the answer to my question is "Yes". 所以我的问题的答案是“是”。

  1. tcpserver really close connection each time after 'handle' tcpserver在'句柄'后每次真正关闭连接
  2. the follow code doesn't work while peer closing 在关闭同伴时,以下代码不起作用

     def handle(self): while 1: try: data = self.request.recv(1024) print self.client_address, "sent", data except: pass 

    this may be better: 这可能会更好:

     def handle(self): while(1): try: self.data = self.request.recv(1024) if not self.data: print "%s close" % self.client_address[0] break print "%s wrote:" % self.client_address[0], self.data except: print "except" break 
    1. reuseaddr doesn't work as it's too late after binding reuseaddr不能正常工作,因为它在绑定后太晚了
     server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

According to the docs , neither TCPServer nor BaseRequestHandler close the socket unless prompted to do so. 根据文档 ,除非提示,否则TCPServer和BaseRequestHandler都不会关闭套接字。 The default implementations of both handle() and finish() do nothing. handle()finish()的默认实现都不做任何事情。

A couple of things might be happening: 可能会发生一些事情:

  • You are closing the socket itself or the request which wraps it, or calling server_close somewhere. 您正在关闭套接字本身或包装它的请求,或在某处调用server_close
  • The socket timeout could have been hit and you have implemented a timeout handler which closes the socket. 套接字超时可能已被命中,您已实现了一个关闭套接字的超时处理程序。
  • The client could be actually closing the socket. 客户端实际上可能正在关闭套接字。 Code would really help figuring this out. 代码真的有助于搞清楚这一点。

However , my testing confirms your results. 但是 ,我的测试证实了您的结果。 Once you return from handle on the server, whether connecting through telnet or Python's socket module, your connection shows up as being closed by the remote host. 从服务器上的handle返回后,无论是通过telnet还是Python的socket模块连接,您的连接都会显示为远程主机关闭。 Handling socket activity in a loop inside handle seems to work: 在句柄内的循环中处理套接字活动似乎有效:

def handle(self):
    while 1:
        try:
            data = self.request.recv(1024)
            print self.client_address, "sent", data
        except:
            pass

A brief Google Code Search confirms that this is a typical way of handling a request: 1 2 3 4 . 简短的Google代码搜索确认这是处理请求的典型方式: 1 2 3 4 Honestly, there are plenty of other networking libraries available for Python that I might look to if I were facing a disconnect between the abstraction SocketServer provides and my expectations. 老实说,如果我面临SocketServer提供的抽象与我的期望之间的脱节,我可能会看到很多其他可用于Python的网络库。

Code sample that I used to test: 我用来测试的代码示例:

from SocketServer import BaseRequestHandler, TCPServer

class TestRequestHandler(BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        print self.client_address, "sent", data
        self.request.send(data)

class TestServer(TCPServer):
    def __init__(self, server_address, handler_class=TestRequestHandler):
        TCPServer.__init__(self, server_address, handler_class)

if __name__ == "__main__":
    import socket

    address = ('localhost', 7734)
    server = TestServer(address)
    server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

You sure the client is not hanging up on the server? 你确定客户端没有挂在服务器上? This is a bit too vague to really tell what is up, but generally a server that is accepting data from a client will quit the connection of the read returns no data. 这有点太模糊了,无法真正告诉它是什么,但通常从客户端接受数据的服务器将退出读取的连接返回没有数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM