-
Notifications
You must be signed in to change notification settings - Fork 1
/
echoserver.py
131 lines (108 loc) · 3.01 KB
/
echoserver.py
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import socket
import sys
import time
__doc__ = """a simple IPv4 TCP echo server"""
def echo(sock):
"""echo data back through the socket"""
if not sock:
return
try:
sock.settimeout(0.0) # non-blocking
except socket.error:
return
failed = 0
while failed < 500:
try:
chunk = sock.recv(1024)
except socket.error:
chunk = ""
if not chunk:
failed += 1
time.sleep(0.001)
else:
failed = 0
try:
sock.sendall(chunk)
except socket.error:
pass
print chunk
def echo_http(sock):
"""preface echoed content with an HTTP response header"""
if not sock:
return
try:
sock.sendall("HTTP/1.1 200 OK\r\n\r\n")
except socket.error:
return
echo(sock)
def _help():
"""print help info to STDOUT"""
print "IPv4 echo server\n" \
"Usage: python echoserver.py [OPTIONS] [ADDRESS]\n" \
"OPTIONS\n" \
"\t-h, --help\tprint help\n" \
"\t--http\tuse HTTP\n" \
"ADDRESS\n" \
"\tan optionally colon-separated address\n" \
"\te.g. [DOMAIN][:PORT]\n" \
"\tdefaults to \"0.0.0.0:80\""
def main():
# argument parsing
domains = "localhost"
port = 80
use_http = False
for arg in sys.argv[1:]:
if arg.startswith("--"):
arg = arg[2:]
if arg == "help":
_help()
sys.exit()
elif arg == "http":
use_http = True
else:
print "Invalid argument."
_help()
sys.exit()
elif arg.startswith('-'):
for c in arg[1:]:
if c == 'h':
_help()
sys.exit()
else:
print "Invalid option."
_help()
sys.exit()
else: # parse
_domains = arg
_port = None
if ':' in arg:
_domains, _port = arg.split(':', 1)
domains = _domains
if _port:
try:
_port = int(_port)
if _port < 0 or _port >= 2 ** 16:
raise ValueError()
port = _port
except ValueError:
pass
# server
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((domains, port))
sock.listen(1)
print "Echo server started on %s:%u" % (domains, port)
try:
while 1:
conn, remote = sock.accept()
if use_http:
echo_http(conn)
else:
echo(conn)
conn.close()
except KeyboardInterrupt:
pass
sock.shutdown(socket.SHUT_RDWR)
sock.close()
if __name__ == "__main__":
main()