2011-08-18 19 views
7

Dzień dobry! I został napisany prosty serwer:Jak utworzyć limit czasu połączenia z pythonem SocketServer

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) 

Jak ustawić limit czasu połączenia. Chcę, gdy klient nie wyśle ​​mi danych i nie jest aktywny w ciągu 30 sekund, serwer zamknie połączenie.

P.S. przepraszam za mój angielski.

UPDATE

#!/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() 

Odpowiedz

3

Proszę spojrzeć na to:

import sys 
import SocketServer 

class SingleTCPHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
     data = self.request.recv(1024) 
     self.request.close() 

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

    timeout = 30 

    daemon_threads = True 
    allow_reuse_address = True 

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

    def handle_timeout(self): 
     print 'Timeout!' 


def running(): 
    server = SimpleServer(('localhost', 6666), SingleTCPHandler) 
    try: 
     #server.serve_forever() 
     server.handle_request() 
    except KeyboardInterrupt: 
     sys.exit(0) 

if __name__ == '__main__': 
    running() 

# vim: filetype=python syntax=python expandtab shiftwidth=4 softtabstop=4 encoding=utf8 

Jeśli chcesz obsługiwać więcej niż jeden wniosek trzeba() ponownie wykonać server.handle_request.

+0

To nie działa dla mnie. Zaczynałem od serwera jako deamon w Linuksie. Wen i ustaw serwer.handle_request(), serwer nie odpowiada:/$ telnet localhost 43 Próbuję :: 1 ... Próbuję 127.0.0.1 ... telnet: Nie można połączyć się ze zdalnym hostem: odmówiono połączenia – user900281

+0

Postanowiłem problem z ustawianiem alarmu (5) w metodzie rączki – user900281

+0

Nie można połączyć się z portem 43, ponieważ serwer nasłuchuje na porcie 6666. Nie wiem, co masz w ustawieniach, ponieważ nie dołączyłeś tej części kodu. – Adam

6

Jeśli używasz StreamRequestHandler zamiast BaseRequestHandler, musisz po prostu zastąpić tam zmienną timeout i zostanie ona ustawiona. Jeśli chcesz dowiedzieć się, jak to zrobić samemu, wystarczy spojrzeć na SocketServer.py

Oto przykład, to zabijać żadnych połączeń, które nie są wykonywane w 5 sekund:

#!/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() 

używa wywołanie Pythona socket settimeout().

Nie sądzę, że twoje rozwiązanie będzie działało z gwintowaniem lub rozwidlaniem.

Powiązane problemy