diff --git a/assignments/session01/echo_client.py b/assignments/session01/echo_client.py index 61616c36..31596da7 100644 --- a/assignments/session01/echo_client.py +++ b/assignments/session01/echo_client.py @@ -6,15 +6,17 @@ def client(msg, log_buffer=sys.stderr): server_address = ('localhost', 10000) # TODO: Replace the following line with your code which will instantiate # a TCP socket with IPv4 Addressing, call the socket you make 'sock' - sock = None + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,socket.IPPROTO_TCP) print >>log_buffer, 'connecting to {0} port {1}'.format(*server_address) # TODO: connect your socket to the server here. + sock.connect(server_address) # this try/finally block exists purely to allow us to close the socket # when we are finished with it try: print >>log_buffer, 'sending "{0}"'.format(msg) # TODO: send your message to the server here. + sock.sendall(msg) # TODO: the server should be sending you back your message as a series # of 16-byte chunks. You will want to log them as you receive @@ -25,11 +27,18 @@ def client(msg, log_buffer=sys.stderr): # Make sure that you log each chunk you receive. Use the print # statement below to do it. (The tests expect this log format) chunk = '' - print >>log_buffer, 'received "{0}"'.format(chunk) + done = False + bufsize = 16 + while not done: + chunk = sock.recv(bufsize) + if len(chunk) < bufsize: + done = True + print >>log_buffer, 'received "{0}"'.format(chunk) finally: # TODO: after you break out of the loop receiving echoed chunks from # the server you will want to close your client socket. print >>log_buffer, 'closing socket' + sock.close() if __name__ == '__main__': @@ -39,4 +48,4 @@ def client(msg, log_buffer=sys.stderr): sys.exit(1) msg = sys.argv[1] - client(msg) \ No newline at end of file + client(msg) diff --git a/assignments/session01/echo_select_server.py b/assignments/session01/echo_select_server.py new file mode 100644 index 00000000..734982ea --- /dev/null +++ b/assignments/session01/echo_select_server.py @@ -0,0 +1,54 @@ +import socket +import sys +import select + + +def server(log_buffer=sys.stderr): + # set an address for our server + address = ('127.0.0.1', 10000) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,socket.IPPROTO_TCP) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + # log that we are building a server + print >>log_buffer, "making a server on {0}:{1}".format(*address) + + sock.bind(address) + sock.listen(5) + + readsocks, writesocks = [], [] + readsocks.append(sock) + + try: + # the outer loop controls the creation of new connection sockets. The + # server will handle each incoming connection one at a time. + while True: + readables, writables, exceptions = select.select(readsocks, writesocks,[]) + for s in readables: + if s == sock: + conn, addr = s.accept() + print >>log_buffer, 'connection - {0}:{1}'.format(*addr) + readsocks.append(conn) + else: + try: + print >> log_buffer, 'read and echo for %d'%id(s) + while True: + data = s.recv(16) + print >>log_buffer, 'received "{0}"'.format(data) + if not data: + break; + s.sendall(data) + finally: + s.close() + readsocks.remove(s) + + + except KeyboardInterrupt: + # TODO: Use the python KeyboardIntterupt exception as a signal to + # close the server socket and exit from the server function. + # Replace the call to `pass` below, which is only there to + # prevent syntax problems + sock.close() + + +if __name__ == '__main__': + server() + sys.exit(0) diff --git a/assignments/session01/echo_server.py b/assignments/session01/echo_server.py index 217380fb..283e858f 100644 --- a/assignments/session01/echo_server.py +++ b/assignments/session01/echo_server.py @@ -7,16 +7,18 @@ def server(log_buffer=sys.stderr): address = ('127.0.0.1', 10000) # TODO: Replace the following line with your code which will instantiate # a TCP socket with IPv4 Addressing, call the socket you make 'sock' - sock = None + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,socket.IPPROTO_TCP) # TODO: Set an option to allow the socket address to be reused immediately # see the end of http://docs.python.org/2/library/socket.html - + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # log that we are building a server print >>log_buffer, "making a server on {0}:{1}".format(*address) # TODO: bind your new sock 'sock' to the address above and begin to listen # for incoming connections - + sock.bind(address) + sock.listen(1) + try: # the outer loop controls the creation of new connection sockets. The # server will handle each incoming connection one at a time. @@ -28,7 +30,7 @@ def server(log_buffer=sys.stderr): # the client so we can report it below. Replace the # following line with your code. It is only here to prevent # syntax errors - addr = ('bar', 'baz') + conn, addr = sock.accept() try: print >>log_buffer, 'connection - {0}:{1}'.format(*addr) @@ -41,12 +43,15 @@ def server(log_buffer=sys.stderr): # following line with your code. It's only here as # a placeholder to prevent an error in string # formatting - data = '' + data = conn.recv(16) print >>log_buffer, 'received "{0}"'.format(data) # TODO: you will need to check here to see if any data was # received. If so, send the data you got back to # the client. If not, exit the inner loop and wait # for a new connection from a client + if not data: + break; + conn.sendall(data) finally: # TODO: When the inner loop exits, this 'finally' clause will @@ -54,16 +59,16 @@ def server(log_buffer=sys.stderr): # created above when a client connected. Replace the # call to `pass` below, which is only there to prevent # syntax problems - pass + conn.close() except KeyboardInterrupt: # TODO: Use the python KeyboardIntterupt exception as a signal to # close the server socket and exit from the server function. # Replace the call to `pass` below, which is only there to # prevent syntax problems - pass + sock.close() if __name__ == '__main__': server() - sys.exit(0) \ No newline at end of file + sys.exit(0) diff --git a/assignments/session01/service_lists.py b/assignments/session01/service_lists.py new file mode 100644 index 00000000..d8a500ca --- /dev/null +++ b/assignments/session01/service_lists.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +import argparse +import socket +import sys + +def service_list(port_bounds): + for i in xrange(*port_bounds): + try: + print >> sys.stderr,"Port %d: %s"% (i, socket.getservbyport(i)) + except socket.error: + print >> sys.stderr, "Port %d: no service" % i + +def main(): + parser = argparse.ArgumentParser(description='Lists the services provided by a given range of ports', + prog='service_lists.py') + parser.add_argument("-p", "--ports", dest = 'port_range', nargs = 2, type = int, + help='port ranges (default: %(default)s)', default= [17, 25]) + args = parser.parse_args() + ports = sorted(args.port_range) + if (ports[0] > 0 and ports[1] < 65535): + pass + else: + print >> sys.stderr, 'Invalid port ranges %s, use default [17,25]' % ports + ports = [17,25] + ports[1] += 1 # to include the upper bound itself + service_list(ports) + +if __name__ == '__main__': + main() diff --git a/assignments/session01/test.sh b/assignments/session01/test.sh new file mode 100755 index 00000000..1ea29db1 --- /dev/null +++ b/assignments/session01/test.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +for n in $(seq 1 100) +do + (python tests.py) & +done