From cadad346f01d3325eab412515ca28ae942b526c7 Mon Sep 17 00:00:00 2001 From: smithre5 Date: Fri, 10 Jan 2014 00:28:12 -0800 Subject: [PATCH] Dick Smith homework submitted --- assignments/session01/echo_client.py | 23 ++++++++--- assignments/session01/echo_server.py | 59 +++++++++++++++++----------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/assignments/session01/echo_client.py b/assignments/session01/echo_client.py index 61616c36..8c761ea1 100644 --- a/assignments/session01/echo_client.py +++ b/assignments/session01/echo_client.py @@ -6,16 +6,20 @@ 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) + 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 # each one. You will also need to check to make sure that @@ -24,12 +28,21 @@ 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) + + amount_received = 0 + amount_expected = len(msg) + chunk = '' + # Look for the response + while amount_received < amount_expected: + chunk = sock.recv(16) + amount_received += len(chunk) + 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 +52,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_server.py b/assignments/session01/echo_server.py index 217380fb..7f6bcc86 100644 --- a/assignments/session01/echo_server.py +++ b/assignments/session01/echo_server.py @@ -1,22 +1,44 @@ import socket import sys +""" +Initial Test sequence: +/c/7_PYTHON/2Q_UW/WEEK_FOLDERS/session01/gitcode_7JanCopy>python +Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 +Type "help", "copyright", "credits" or "license" for more information. +>>> import echo_server +>>> echo_server.server() +making a server on 127.0.0.1:10000 +waiting for a connection +. . . (I invoked here) . . . +/c/7_PYTHON/2Q_UW/WEEK_FOLDERS/session01/gitcode_7JanCopy> +""" def server(log_buffer=sys.stderr): # set an address for our server address = ('127.0.0.1', 10000) + MAX_SERVER_CONNECTIONS = 1 # 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 + # solution: This could have been "default", but wanted to be explicit. + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # 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 - + # solution: as a socket jockey from C/C++, I know about SO_REUSEADDR, + # and I know python socket is a thinly wrapped interface to C libraries, + # so I just googled 'python setsockopt SO_REUSEADDR'. + # This must be executed before bind is called in order to work. + 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(MAX_SERVER_CONNECTIONS) + try: # the outer loop controls the creation of new connection sockets. The # server will handle each incoming connection one at a time. @@ -25,43 +47,36 @@ def server(log_buffer=sys.stderr): # TODO: make a new socket when a client connects, call it 'conn', # at the same time you should be able to get the address of - # 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') + # the client so we can report it below. + conn, client_addr = sock.accept() try: - print >>log_buffer, 'connection - {0}:{1}'.format(*addr) + print >>log_buffer, 'connection - {0}:{1}'.format(*client_addr) # the inner loop will receive messages sent by the client in # buffers. When a complete message has been received, the # loop will exit while True: # TODO: receive 16 bytes of data from the client. Store - # the data you receive as 'data'. Replace the - # following line with your code. It's only here as - # a placeholder to prevent an error in string - # formatting - data = '' + # the data you receive as '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('%s' % (data)) finally: # TODO: When the inner loop exits, this 'finally' clause will # be hit. Use that opportunity to close the socket you - # created above when a client connected. Replace the - # call to `pass` below, which is only there to prevent - # syntax problems - pass + # created above when a client connected. + conn.close() except KeyboardInterrupt: - # TODO: Use the python KeyboardIntterupt exception as a signal to + # TODO: Use the python KeyboardInterrupt 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__':