From 22825e86f6e13a4d84822ae9ee7c8a807259f37d Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 1 Jul 1991 18:32:32 +0000 Subject: [PATCH] Initial revision --- Demo/sockets/README | 7 +++ Demo/sockets/echosvr.py | 31 +++++++++++ Demo/sockets/finger.py | 58 ++++++++++++++++++++ Demo/sockets/telnet.py | 109 +++++++++++++++++++++++++++++++++++++ Demo/sockets/throughput.py | 93 +++++++++++++++++++++++++++++++ Demo/sockets/udpecho.py | 63 +++++++++++++++++++++ 6 files changed, 361 insertions(+) create mode 100644 Demo/sockets/README create mode 100755 Demo/sockets/echosvr.py create mode 100755 Demo/sockets/finger.py create mode 100755 Demo/sockets/telnet.py create mode 100755 Demo/sockets/throughput.py create mode 100755 Demo/sockets/udpecho.py diff --git a/Demo/sockets/README b/Demo/sockets/README new file mode 100644 index 00000000000..463ab1cd228 --- /dev/null +++ b/Demo/sockets/README @@ -0,0 +1,7 @@ +Contents of this directory: + +echosvr.py About the simplest TCP server possible. +finger.py Client for the 'finger' protocol. +telnet.py Client for the 'telnet' protocol. +throughput.py Client and server to measure TCP throughput. +udpecho.py Client and server for the UDP echo protocol. diff --git a/Demo/sockets/echosvr.py b/Demo/sockets/echosvr.py new file mode 100755 index 00000000000..f2455837b93 --- /dev/null +++ b/Demo/sockets/echosvr.py @@ -0,0 +1,31 @@ +#! /usr/local/python + +# Python implementation of an 'echo' tcp server: echo all data it receives. +# +# This is the simplest possible server, sevicing a single request only. + +import sys +from socket import * + +# The standard echo port isn't very useful, it requires root permissions! +# ECHO_PORT = 7 +ECHO_PORT = 50000 + 7 +BUFSIZE = 1024 + +def main(): + if len(sys.argv) > 1: + port = int(eval(sys.argv[1])) + else: + port = ECHO_PORT + s = socket(AF_INET, SOCK_STREAM) + s.bind('', port) + s.listen(0) + conn, (host, remoteport) = s.accept() + print 'connected by', host, remoteport + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + conn.send(data) + +main() diff --git a/Demo/sockets/finger.py b/Demo/sockets/finger.py new file mode 100755 index 00000000000..8aa05352c82 --- /dev/null +++ b/Demo/sockets/finger.py @@ -0,0 +1,58 @@ +#! /usr/local/python + +# Python interface to the Internet finger daemon. +# +# Usage: finger [options] [user][@host] ... +# +# If no host is given, the finger daemon on the local host is contacted. +# Options are passed uninterpreted to the finger daemon! + + +import sys, string +from socket import * + + +# Hardcode the number of the finger port here. +# It's not likely to change soon... +# +FINGER_PORT = 79 + + +# Function to do one remote finger invocation. +# Output goes directly to stdout (although this can be changed). +# +def finger(host, args): + s = socket(AF_INET, SOCK_STREAM) + s.connect(host, FINGER_PORT) + s.send(args + '\n') + while 1: + buf = s.recv(1024) + if not buf: break + sys.stdout.write(buf) + sys.stdout.flush() + + +# Main function: argument parsing. +# +def main(): + options = '' + i = 1 + while i < len(sys.argv) and sys.argv[i][:1] = '-': + options = options + sys.argv[i] + ' ' + i = i+1 + args = sys.argv[i:] + if not args: + args = [''] + for arg in args: + if '@' in arg: + at = string.index(arg, '@') + host = arg[at+1:] + arg = arg[:at] + else: + host = '' + finger(host, options + arg) + + +# Call the main function. +# +main() diff --git a/Demo/sockets/telnet.py b/Demo/sockets/telnet.py new file mode 100755 index 00000000000..60f832aac9d --- /dev/null +++ b/Demo/sockets/telnet.py @@ -0,0 +1,109 @@ +#! /usr/local/python + +# Minimal interface to the Internet telnet protocol. +# +# It refuses all telnet options and does not recognize any of the other +# telnet commands, but can still be used to connect in line-by-line mode. +# It's also useful to play with a number of other services, +# like time, finger, smtp and even ftp. +# +# Usage: telnet host [port] +# +# The port may be a service name or a decimal port number; +# it defaults to 'telnet'. + + +import sys, posix, time +from socket import * + +BUFSIZE = 1024 + +# Telnet protocol characters + +IAC = chr(255) # Interpret as command +DONT = chr(254) +DO = chr(253) +WONT = chr(252) +WILL = chr(251) + +def main(): + host = sys.argv[1] + try: + hostaddr = gethostbyname(host) + except error: + sys.stderr.write(sys.argv[1] + ': bad host name\n') + sys.exit(2) + # + if len(sys.argv) > 2: + servname = sys.argv[2] + else: + servname = 'telnet' + # + if '0' <= servname[:1] <= '9': + port = eval(servname) + else: + try: + port = getservbyname(servname, 'tcp') + except error: + sys.stderr.write(servname + ': bad tcp service name\n') + sys.exit(2) + # + s = socket(AF_INET, SOCK_STREAM) + # + try: + s.connect(host, port) + except error, msg: + sys.stderr.write('connect failed: ' + `msg` + '\n') + sys.exit(1) + # + pid = posix.fork() + # + if pid = 0: + # child -- read stdin, write socket + while 1: + line = sys.stdin.readline() + s.send(line) + else: + # parent -- read socket, write stdout + iac = 0 # Interpret next char as command + opt = '' # Interpret next char as option + while 1: + data = s.recv(BUFSIZE) + if not data: + # EOF; kill child and exit + sys.stderr.write( '(Closed by remote host)\n') + posix.kill(pid, 9) + sys.exit(1) + cleandata = '' + for c in data: + if opt: + print ord(c) + s.send(opt + c) + opt = '' + elif iac: + iac = 0 + if c = IAC: + cleandata = cleandata + c + elif c in (DO, DONT): + if c = DO: print '(DO)', + else: print '(DONT)', + opt = IAC + WONT + elif c in (WILL, WONT): + if c = WILL: print '(WILL)', + else: print '(WONT)', + opt = IAC + DONT + else: + print '(command)', ord(c) + elif c = IAC: + iac = 1 + print '(IAC)', + else: + cleandata = cleandata + c + sys.stdout.write(cleandata) + sys.stdout.flush() + + +try: + main() +except KeyboardInterrupt: + pass diff --git a/Demo/sockets/throughput.py b/Demo/sockets/throughput.py new file mode 100755 index 00000000000..411af9f42e6 --- /dev/null +++ b/Demo/sockets/throughput.py @@ -0,0 +1,93 @@ +#! /usr/local/python + +# Test network throughput. +# +# Usage: +# 1) on host_A: throughput -s [port] # start a server +# 2) on host_B: throughput -c count host_A [port] # start a client +# +# The server will service multiple clients until it is killed. +# +# The client performs one transfer of count*BUFSIZE bytes and +# measures the time it takes (roundtrip!). + + +import sys, time +from socket import * + +MY_PORT = 50000 + 42 + +BUFSIZE = 1024 + + +def main(): + if len(sys.argv) < 2: + usage() + if sys.argv[1] = '-s': + server() + elif sys.argv[1] = '-c': + client() + else: + usage() + + +def usage(): + sys.stdout = sys.stderr + print 'Usage: (on host_A) throughput -s [port]' + print 'and then: (on host_B) throughput -c count host_A [port]' + sys.exit(2) + + +def server(): + if len(sys.argv) > 2: + port = eval(sys.argv[2]) + else: + port = MY_PORT + s = socket(AF_INET, SOCK_STREAM) + s.bind('', port) + s.listen(0) + print 'Server ready...' + while 1: + conn, (host, remoteport) = s.accept() + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + del data + conn.send('OK\n') + conn.close() + print 'Done with', host, 'port', remoteport + + +def client(): + if len(sys.argv) < 4: + usage() + count = int(eval(sys.argv[2])) + host = sys.argv[3] + if len(sys.argv) > 4: + port = eval(sys.argv[4]) + else: + port = MY_PORT + testdata = 'x' * (BUFSIZE-1) + '\n' + t1 = time.millitimer() + s = socket(AF_INET, SOCK_STREAM) + t2 = time.millitimer() + s.connect(host, port) + t3 = time.millitimer() + i = 0 + while i < count: + i = i+1 + s.send(testdata) + s.shutdown(1) # Send EOF + t4 = time.millitimer() + data = s.recv(BUFSIZE) + t5 = time.millitimer() + print data + print 'Raw timers:', t1, t2, t3, t4, t5 + print 'Intervals:', t2-t1, t3-t2, t4-t3, t5-t4 + print 'Total:', t5-t1 + print 'Throughput:', int(float(BUFSIZE*count) / float(t5-t1)), + print 'K/sec.' + + +main() diff --git a/Demo/sockets/udpecho.py b/Demo/sockets/udpecho.py new file mode 100755 index 00000000000..53dff64ebde --- /dev/null +++ b/Demo/sockets/udpecho.py @@ -0,0 +1,63 @@ +#! /usr/local/python + +# Client and server for udp (datagram) echo. +# +# Usage: udpecho -s [port] (to start a server) +# or: udpecho -c host [port] 2: + port = eval(sys.argv[2]) + else: + port = ECHO_PORT + s = socket(AF_INET, SOCK_DGRAM) + s.bind('', port) + print 'udp echo server ready' + while 1: + data, addr = s.recvfrom(BUFSIZE) + print 'server received', `data`, 'from', `addr` + s.sendto(data, addr) + +def client(): + if len(sys.argv) < 3: + usage() + host = sys.argv[2] + if len(sys.argv) > 3: + port = eval(sys.argv[3]) + else: + port = ECHO_PORT + addr = host, port + s = socket(AF_INET, SOCK_DGRAM) + s.bind('', 0) + print 'udp echo client ready, reading stdin' + while 1: + line = sys.stdin.readline() + if not line: + break + s.sendto(line, addr) + data, fromaddr = s.recvfrom(BUFSIZE) + print 'client received', `data`, 'from', `fromaddr` + +main()