gpt4 book ai didi

Python 关闭线程服务器中的套接字和连接?

转载 作者:行者123 更新时间:2023-12-01 07:18:19 25 4
gpt4 key购买 nike

我们有一个 Python 套接字线程服务器示例。这是一个稍加修改的版本 https://stackoverflow.com/a/23828265/2008247 。该示例有效,并且我的测试证实它的性能比阻塞服务器更好。

但在示例中,套接字和连接对象并未关闭。这两个对象都有 close() 方法。 (连接上的 close 方法仅在异常时调用。我希望在每个连接结束时调用它。)我们不需要以某种方式调用它们吗?如果是这样,怎么办?

#!/usr/bin/env python

import socket
import threading

class ThreadedServer():

def __init__(self, host, port):

self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))

def listen(self):

self.sock.listen(5)

while True:

con, address = self.sock.accept()
con.settimeout(60)
threading.Thread(target=self.listenToClient,
args=(con, address)).start()

def listenToClient(self, con, address):

while True:
try:
data = con.recv(1024)
if data:
# Set the response to echo back the recieved data
response = data
con.send(response)
else:
raise Exception('Client disconnected')
except:
con.close()
return False


def main():

ThreadedServer('', 8001).listen()


if __name__ == "__main__":
main()

最佳答案

根据[Python.Docs]: socket.close() :

Sockets are automatically closed when they are garbage-collected, but it is recommended to close() them explicitly, or to use a with statement around them.

因此,所有套接字最终都会被关闭。但是,如果服务器运行很长时间并且(快速)创建/销毁大量连接,您可能最终会遇到文件描述符耗尽的情况,因此无法创建新的套接字,因此它是最好手动关闭它们。

有2个案例。

1。关闭服务器套接字

事情很简单。添加一个“析构函数”,或者更好的:终结器 ( [Python.Docs]: Data model - object.__del__(self) ) 到您的 ThreadedServer 类中:

def __del__(self):
#print("Closing server socket:", self.sock)
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()

这并不是真正必要的,因为服务器将在程序结束时被销毁,并且所有资源无论如何都会在此时被释放。

2。关闭每个客户端套接字

或者:

  • finally 子句 ( [Python.Docs]: Compound statements - The try statement ) 添加到 listenToClient 中的 try (此时,您还可以将该方法重命名为类似 listen_to_client):

    # ...
    try:
    # Socket operation that might raise exceptions (con.recv)
    except:
    return False
    finally:
    #print("Closing connection:", con)
    con.shutdown(socket.SHUT_RDWR)
    con.close()
  • 扩展Thread类,并在ThreadedServer.listen中使用它(这更优雅):

    class ConnectionHandlingThread(threading.Thread):
    def __init__(self, target, connection, address):
    self.connection = connection
    super().__init__(target=target, args=(connection, address))

    def run(self):
    super().run()
    #print("Closing connection:", self.connection)
    self.connection.shutdown(socket.SHUT_RDWR)
    self.connection.close()

    及其用法:

    ConnectionHandlingThread(listen_to_client, con, address).start()

替代方案

这一切看起来有点像重新发明轮子。这个具体场景的样板已存在于 socketserver 模块(Python 标准库的一部分)中。更多详情请查看[Python.Docs]: socketserver - Asynchronous Mixins .

关于Python 关闭线程服务器中的套接字和连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57841263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com