Good day! I was writen simple server:
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)
How to set connection timeout. I want when the client not send me data and is not active in 30 seconds, server will close connection.
P.S. sorry for my english.
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()
You can make an instance of a socket object and call a gettimeout() method to get the default timeout value and the settimeout() method to set a specific timeout value.
Answer: Just set the SO_TIMEOUT on your Java Socket, as shown in the following sample code: String serverName = "localhost"; int port = 8080; // set the socket SO timeout to 10 seconds Socket socket = openSocket(serverName, port); socket. setSoTimeout(10*1000);
A new Python socket by default doesn't have a timeout. Its timeout defaults to None. Not setting the connection timeout parameter can result in blocking socket mode. In blocking mode, operations block until complete or the system returns an error.
socket timeout — a maximum time of inactivity between two data packets when exchanging data with a server.
If you use StreamRequestHandler instead of BaseRequestHandler, you just need to override the timeout variable there, and it will be set. If you want to learn how to do it yourself, just look at the SocketServer.py
Here's an example, this will kill any connections that aren't done in 5 seconds:
#!/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()
This uses the python's socket settimeout() call.
I don't think your alarm()
solution will work with threading or forking.
Please look at it:
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
If you want to handle more than one request you need to execute server.handle_request() again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With