gpt4 book ai didi

python - 如何使用 python SocketServer 创建连接超时

转载 作者:太空狗 更新时间:2023-10-29 21:38:08 24 4
gpt4 key购买 nike

美好的一天!我被写成简单的服务器:

class SingleTCPHandler(SocketServer.BaseRequestHandler):

def handle(self):
data = self.request.recv(1024)
self.request.close()

class SimpleServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):

daemon_threads = True

allow_reuse_address = True

def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)


def running():
server = SimpleServer((settings.host, settings.port), SingleTCPHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)

如何设置连接超时。我希望当客户端不向我发送数据并且在 30 秒内不活动时,服务器将关闭连接。

附言对不起我的英语不好。

更新

#!/usr/bin/env python
# -*- coding: utf8 -*-

import sys
import time

import SocketServer
import datetime
import settings
import os
from signal import SIGTERM, SIGCHLD, signal, alarm
import socket
import subprocess
from threading import Thread
import MySQLdb
import re

class SingleTCPHandler(SocketServer.BaseRequestHandler):
"One instance per connection. Override handle(self) to customize action."
def handle(self):
alarm(30)
data = self.request.recv(1024)
# Some code
self.request.close()


class SimpleServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):

daemon_threads = True
allow_reuse_address = True


def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)




def running():
server = SimpleServer((settings.host, settings.port), SingleTCPHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)


def deamonize(stdout='/dev/null', stderr=None, stdin='/dev/null', pidfile=None, startmsg='started with pid %s'):
try:
pid = os.fork()
if (pid > 0):
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
sys.exit(1)

os.chdir(settings.place)
os.umask(0)
os.setsid()

try:
pid = os.fork()
if (pid > 0):
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
sys.exit(1)

if (not stderr):
stderr = stdout

print stdin, stdout, stderr
si = file(stdin, 'r')
so = file(stdout, 'a+')
se = file(stderr, 'a+', 0)
pid = str(os.getpid())
sys.stderr.write("\n%s\n" % startmsg % pid)
sys.stderr.flush()
if pidfile: file(pidfile, 'w+').write("%s\n" % pid)

os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())

def startstop(stdout='/dev/null', stderr=None, stdin='/dev/null', pidfile='pid.txt', startmsg='started with pid %s'):
if len(sys.argv) > 1:
action = sys.argv[1]
try:
pf = open(pidfile)
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if ((action == 'stop') or (action == 'restart')):
if (not pid):
mess = "Не могу остановить, pid файл '%s' отсутствует.\n"
sys.stderr.write(mess % pidfile)
sys.exit(1)
try:
while 1:
os.kill(pid, SIGTERM)
time.sleep(1)
except OSError, err:
err = str(err)
if err.find("No such process") > 0:
os.remove(pidfile)
if 'stop' == action:
sys.exit(0)
action = 'start'
pid = None
else:
print str(err)
sys.exit(1)
if ('start' == action):
if (pid):
mess = "Старт отменен — pid файл '%s' существует.\n"
sys.stderr.write(mess % pidfile)
sys.exit(1)
deamonize(stdout, stderr, stdin, pidfile, startmsg)
return
print "Синтакс запуска: %s start|stop|restart" % sys.argv[0]
sys.exit(2)

if (__name__ == "__main__"):
startstop(stdout=settings.log, pidfile=settings.pid)
running()

最佳答案

如果你使用 StreamRequestHandler 而不是 BaseRequestHandler,你只需要覆盖那里的超时变量,它就会被设置。如果您想自己学习如何做,只需查看 SocketServer.py

这是一个示例,这将终止所有未在 5 秒内完成的连接:

#!/usr/bin/env python
import SocketServer

class myHandler(SocketServer.StreamRequestHandler):
timeout = 5
def handle(self):
recvdata = ""
while True:
tmp = self.request.recv(16384)
recvdata = recvdata + tmp.strip()
if (len(tmp) < 16384):
break;
self.request.send("Received: {0}".format(recvdata))

class myApp(SocketServer.TCPServer):

def __init__(self):
SocketServer.TCPServer.__init__(self, ("localhost", 5555), myHandler)
print self.server_address
try:
self.serve_forever()
except KeyboardInterrupt:
print "Got keyboard interrupt, shutting down"
self.shutdown()

if __name__ == "__main__":
app = myApp()

这使用了 python 的 socket settimeout()打电话。

我认为您的alarm() 解决方案不适用于线程或 fork 。

关于python - 如何使用 python SocketServer 创建连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7105431/

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