gpt4 book ai didi

python - 在连续运行的python脚本中保持端口打开

转载 作者:太空宇宙 更新时间:2023-11-04 12:15:47 29 4
gpt4 key购买 nike

我正在尝试使用 python 3.4 开发一个服务器脚本,该脚本永久运行并响应最多 5 个独立端口上的客户端请求。我的首选平台是 Debian 8.0。该平台目前在云中的虚拟机上运行。当我从命令行运行它时,我的脚本工作正常 - 我现在需要 (1) 在我注销服务器后保持它运行,以及 (2) 通过脚本保持几个端口打开,以便 Windows 客户端可以连接到它们。

对于 (1),

在尝试了几个似乎没有用的选项后 [我尝试使用 upstart,将脚本添加到 rc.local,使用 nohup 和 & 从终端运行它,等等],我最终发现了一些似乎确实有效的方法保持脚本运行,即使它不是很优雅——我写了一个每小时一次的 cron 脚本,检查脚本是否在进程列表中运行,如果没有,则执行它。

每当我现在登录到虚拟机时,当我输入“ps -ef”时,我会看到以下输出:

root 22007 21992 98 Nov10 14-12:52:59/usr/bin/python3.4/home/userxyz/cronserver.py

我假设脚本正在运行,因为系统中有一个事件进程。我提到这部分是因为我怀疑这可能与我的问题的第 (2) 部分相关。

对于(2),

该脚本应该打开端口 49100 - 49105 并监听连接请求等。当我从终端运行脚本时,我的客户端机器上的 zenmap 会验证这些端口是否打开。但是,当 cron 作业启动脚本时,这些端口似乎并没有保持打开状态。我的 Windows 客户端程序也无法连接到脚本。

我用来监听端口的python代码:

    f = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
f.bind((serviceIP, 49101))
f.listen(5)
while True:
scName, address = f.accept()

[code to handle request]

scName.shutdown(socket.SHUT_WR)
scName.close()

如有任何见解或帮助,我们将不胜感激!

最佳答案

您提出的问题并不容易,因为它取决于多种因素:

  • 接收数据的频率是多少?
  • 预计有多少客户端连接到此服务器?
    • 是否有可能有两个客户端同时尝试连接?
  • 处理一些接收到的数据需要多长时间?
  • 您需要如何处理您的数据?
    • 写入数据库?
    • 写入文件?
    • 计算什么?

根据您的回答,您需要为您的解决方案做出一些设计决策。

但由于您需要答案,这里有一个 hack 代表了一种做事的方式:

import socketserver
import threading
import datetime

class SleepyGaryReceptionHandler(socketserver.BaseRequestHandler):

log_file_name = "/tmp/sleepygaryserver.log"

def handle(self):

# self.request is defined in BaseRequestHandler
data_received = self.request.recv(1024)
# self.client_address is also defined in BaseRequestHandler
sender_address = self.client_address[0]

# This is where you are supposed to do something with your data
# This is an example
self.write_to_log('Someone from {} sent us "{}"'.format(sender_address,
data_received))

# A way to stop the server from going on forever
# But you could do this other ways but it depends what condition
# should cause the shutdown
if data_received.startswith(b"QUIT"):
finishing_thread = threading.Thread(target=self.finish_in_another_thread)
finishing_thread.start()

# This will be called in another thread to terminate the server
# self.server is also defined in BaseRequestHandler
def finish_in_another_thread(self):
self.write_to_log("Shutting down the server")
self.server.shutdown()

# Write something (with a timestamp) to a text file so that we
# know something is happenning
def write_to_log(self, message):
timestamp = datetime.datetime.now()
timestamp_text = timestamp.isoformat(sep=' ', timespec='seconds')
with open(self.log_file_name, mode='a') as log_file:
log_file.write("{}: {}\n".format(timestamp_text, message))

service_address = "localhost"
port_number = 49101

server = socketserver.TCPServer((service_address, port_number),
SleepyGaryReceptionHandler)
server.serve_forever()

我在这里使用 socketserver模块而不是直接在套接字上监听。这个标准库模块是为了简化服务器的编写而编写的。所以使用它!

我在这里所做的就是将收到的内容写入文本文件。您必须根据自己的用途对其进行调整。

但要让它连续运行,请使用 cron 作业,但要在计算机启动时启动它。由于此脚本将阻塞直到服务器停止,因此我们必须在后台运行它。它看起来像这样:

 @reboot /usr/bin/python3 /home/sleepygary/sleppys_server.py &

我已经对其进行了测试,5 小时后它仍然可以正常工作。

现在就像我说的,这是一个 hack。如果您想一路走下去并像计算机上的任何其他服务一样做事,则必须以某种方式对其进行编程。您可以在此页面上找到更多信息:https://www.freedesktop.org/software/systemd/man/daemon.html

我真的很累所以可能会有一些错误。

关于python - 在连续运行的python脚本中保持端口打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47483033/

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