Seite 1 von 1

grundfragen für mini-webserver

Verfasst: Donnerstag 14. Juni 2007, 05:33
von Volvic
hallo :)

ich bin neu hier im forum und habe auch schon gleich ein paar fragen. ich möchte für ein projekt an dem ich arbeite einen minimalistischen webserver erstellen, der multithreaded sein soll. ich möchte nicht unbedingt das per SCGI/FCGI machen, da ich für derart kleine projekte darin keinen nutzen sehe. durch die forum suche und google habe ich vieles nützliches gefunden, aber je mehr ich gelesen habe desto mehr fragen blieben offen, diese wären:

- ich zweifel etwas ob eine variante mit SCGI/FCGI nicht besser wäre aus der performance sicht her, da nativer code um einiges schneller ist. die idee nen webserver komplett in python, wurde diese schon von anderen projekten verwirklicht und wenn ja mit erfolg?
- sind non-blocking sockets schneller als blocking, wenn ja warum?
- python kann ja kein echtes multithreading in dem sinne, gibt es eine maximal anzahl an threads?
- würde sich für ein multithreaded webserver nicht soetwas wie stackless python eignen, performance technisch?

etwas code habe ich durchs forum nun, funktioniert auch gut bis auf non-blocking sockets, die machen mir noch zu schaffen:

Code: Alles auswählen

import socket
import threading

CFG_DEBUG = True
CFG_HOST = '127.0.0.1'
CFG_PORT = 8080
CFG_LQUEUE = 5

html = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
	<head>
		<title>testseite</title>
		<style type="text/css">
			body {
				font-family: Verdana, Helvetica, sans-serif;
				font-size: small;
			}
		</style>
	</head>

	<body>
		<div style="width: 950px;">
			<p>hallo welt!</p>
		</div>
	</body>
</html>'''

class ReqHandler(threading.Thread):
	def __init__(self, psock, paddr):
		threading.Thread.__init__(self)
		self.csock = psock
		self.caddr = paddr
	
	def send_stream(self, status, mimetype, conn, bindata):
		self.csock.send('HTTP/1.1 %s\nServer: Testserver/0.1\nContent-Length: %d\nConnection: %s\nContent-Type: %s\n\n' % (status, len(bindata), conn, mimetype))
		self.csock.send(bindata)
	
	def run(self):
		try:
			while True:
				data = self.csock.recv(4096)
				if not data:
					self.csock.close()
					if CFG_DEBUG: print 'DEBUG: 0 bytes received, close socket.'
					break
				if CFG_DEBUG: print 'DEBUG: received data from socket.'
				print data
				self.send_stream('200 OK', 'text/html', 'Keep-Alive', html)
				if CFG_DEBUG: print 'DEBUG: data send to socket.'
			self.csock.close()
		except:
			self.csock.close()
			if CFG_DEBUG: print 'DEBUG: exception in thread.'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((CFG_HOST, CFG_PORT))
s.listen(CFG_LQUEUE)

print 'webserver start erfolgt...'
if CFG_DEBUG:
	print 'DEBUG.: on'
print ''

while True:
	(sock, addr) = s.accept()
	client = ReqHandler(sock, addr)
	client.start()
	if CFG_DEBUG: print 'DEBUG: thread started.'
s.close()
ich freue mich über jegliche hilfe :)

Verfasst: Donnerstag 14. Juni 2007, 05:58
von mitsuhiko
Warum immer alles selber machen? Hier ein WSGI Server mit Threading Funktionalität: http://lucumr.pocoo.org/trac/repos/BaseWSGIServer.py

Verfasst: Donnerstag 14. Juni 2007, 06:43
von EnTeQuAk
Also der BaseWSGIServer is nur zu empfehlen. Besonders wenns klein und schlank sein soll.

Für mehr Features: http://svn.cherrypy.org/trunk/cherrypy/ ... _init__.py

Hier hast du z.B. SSL Support und viele andere Sachen, die man ab und zu brauchen könnte :)


MfG EnTeQuAk

@blackbird: Was ist eigentlich aus James geworden, wurde das Projekt eingestellt?

Verfasst: Donnerstag 14. Juni 2007, 13:26
von mitsuhiko
EnTeQuAk hat geschrieben:@blackbird: Was ist eigentlich aus James geworden, wurde das Projekt eingestellt?
paste, cherrypy, wsgiref, warum also noch ein Server :)

Verfasst: Donnerstag 14. Juni 2007, 14:05
von EyDu
Schau dir mal die Klassen: "SocketServer.ThreadingTCPServer" und "HTTPServer.HTTPServer" an. Das scheint mir genau das zu sein, was du suchst.