Initial revision

This commit is contained in:
Guido van Rossum 1991-07-01 18:32:32 +00:00
parent 2fa5a7fc00
commit 22825e86f6
6 changed files with 361 additions and 0 deletions

7
Demo/sockets/README Normal file
View File

@ -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.

31
Demo/sockets/echosvr.py Executable file
View File

@ -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()

58
Demo/sockets/finger.py Executable file
View File

@ -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()

109
Demo/sockets/telnet.py Executable file
View File

@ -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

93
Demo/sockets/throughput.py Executable file
View File

@ -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()

63
Demo/sockets/udpecho.py Executable file
View File

@ -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] <file (client)
import sys
from socket import *
ECHO_PORT = 50000 + 7
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: udpecho -s [port] (server)'
print 'or: udpecho -c host [port] <file (client)'
sys.exit(2)
def server():
if len(sys.argv) > 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()