1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
| #!/usr/bin/env stackless
# stackless is a symlink to Stackless Python's binary.
# Change to python instead to run the standard interpreter,
# such as: #!/usr/bin/env python
# Simple socket server using select() in a separate thread.
import os, sys, select, signal, socket, thread, threading, time
source_file = "/path/to/html/document"
class SelectServer (threading.Thread):
config = {}
server = None
total = 0
inputs = []
def __init__(self):
threading.Thread.__init__(self, name="SelectLoop")
#signal.signal(signal.SIGINT, self.shutdown())
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Reuse the address so we don't get binding issues.
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind(("0.0.0.0", 34567))
print "Socket (Internet) opened."
self.server.listen(socket.SOMAXCONN)
self.server.settimeout(300)
def run (self):
self.inputs = [self.server]
while True:
#print "loop"
try:
input, output, ex = select.select(self.inputs, [], [])
except select.error:
break
for sock in input:
try:
if sock == self.server:
self.new_client(sock)
else:
self.read_client(sock)
except socket.error, e:
print "Connection closed."
sock.close()
self.inputs.remove(sock)
def shutdown (self):
#if self.config["socket.type"] == "domain":
# print "Removing domain socket."
# os.remove(self.config["socket.file"])
sys.exit(0)
def new_client (self, sock):
client, address = self.server.accept()
self.inputs.append(client)
#print "Connection %d " % (self.total + 1)
self.total += 1
def read_client (self, sock):
buf = ""
line = False
while True:
c = sock.recv(1)
if buf[-1:] == "r" and c == "n" and not line:
line = True
buf += c
continue
elif buf[-1:] == "r" and c == "n" and line:
buf += c
break
elif line and (c != "r" and c != "n"):
line = False
buf += c
if not c:
print "closing"
break
data = open(source_file).read()
output = ("HTTP/1.1 200 OK\r\n"+
"Server: DESTRealm-Test\r\n"+
"Content-Type: text/html\r\n")
output += "Content-Length: %d\r\n" % len(data)
output += "Date: Sat, 14 Feb 2009 00:18:56 GMT\r\n\r\n"
output += data
# No actual processing of the HTTP headers is performed since this
# is EXCLUSIVELY intended for testing the performance of a raw
# select() server.
sock.sendall(output)
sock.close()
self.inputs.remove(sock)
if __name__ == "__main__":
try:
t = SelectServer()
t.start()
while 1:
#print "Ping!"
time.sleep(1)
except KeyboardInterrupt:
print "Shutting down..."
sys.exit(0) |
2 Responses to “Brief Comparison of Servers and Frameworks”
O_O
Wow. Glad you did that rather than me. Would have took me forever to screw around with this.
You’d be surprised! I’ve been working on collecting data for this benchmark off and on for a while. I do need to change the graphs, though. With as many lines as there are, I’m afraid it’s getting cluttered. Displaying a comparison of mean values as bars might be easier on the eyes!
The results are still very interesting. It’s just a shame that some of the standard library stuff works so poorly. Though, it isn’t surprising; much of that is intended as example code.
Leave a comment