Software Design Lecture Notes Fall 2004 Network programming ------------------- 1) low-level communication: sockets 2) medium-level protocol modules 3) high-level distributed programming: remote objects Sockets ------- A socket is a software object that allows a process to connect to a port. A process is a running program. There might be more than one process running the same program. A port is a mailbox that is visible from other computers. Clients and servers ------------------- A common way to organize a distributed computation is with different processes that act as clients and servers. 1) The Web is a client-server system Web browsers are clients They connect to servers, as specified by URLs Servers wait for connections, receive requests, lookup files, send replies. Many servers, many clients. Most servers run all the time. Clients are intermittent. 2) A (relatively) simple example: An echo server waits for connections, receives data, "echos" the data back to the client. One server, one client (at a time). ### SERVER from socket import * HOST = '' # Symbolic name meaning the local host PORT = 50007 # Arbitrary non-privileged port lsock = socket(AF_INET, SOCK_STREAM) lsock.bind((HOST, PORT)) lsock.listen(1) csock, addr = lsock.accept() print 'Server connected to:', csock.getpeername() while 1: data = csock.recv(1024) if not data: break print 'Server received', `data` csock.send(data) csock.close() lsock.close() ### CLIENT from socket import * HOST = 'rocky.olin.edu' # The remote host PORT = 50007 # The same port as used by the server csock = socket(AF_INET, SOCK_STREAM) csock.connect((HOST, PORT)) print 'Client connected to: ', csock.getpeername() csock.send('Hello, world') data = csock.recv(1024) csock.close() print 'Client received', `data` 1) port numbers: some "well-known" numbers are reserved for particular functions others are available for transient use 2) bind: associate a socket with a particular port 3) listen: make this socket into a (passive) listening socket servers use this method; clients don't 4) accept: wait for a client to connect, and return a tuple lsock is the listening socket csock is the connected socket addr is the address of the client 5) send/recv: can only send and receive strings! 6) connect: clients invoke connect to specify the HOST and PORT of the server (How do they know???) Pros and Cons of sockets ------------------------ +) versatile and powerful -) complicated -) can only send and receive strings! +) can implement any protocol -) have to implement any protocol Protocol modules ---------------- There are built-in (or readily-available) modules that work with many common protocols. For example, urllib 1) parses URLs into (protocol, server, file) 2) opens a socket and connects to the server 3) sends a legal HTTP GET request 4) reads and parses the response 5) returns an object that can be used to access the response Documentation at www.python.org/doc/current/lib/module-urllib.html Example: from urllib import * conn = urlopen('http://rocky.olin.edu/sd/code/World.py') print conn for line in conn.fp: print line, OR print conn.read() Pros and cons of protocol modules --------------------------------- +) easy to work with existing protocols +) useful tools for both the server and client end -) not as versatile as sockets Remote objects -------------- A little more cutting edge, not in standard modules. But I found something pretty good in the Vaults: Pyro (Python Remote Objects). Concepts today, details next time. 1) the server a) creates an object that will be available remotely b) advertises the object on a name server 2) the client a) contacts the name server to find a remote object b) creates a local object that acts as a PROXY for the remote object c) invokes methods on the proxy 3) the middleware (Pyro) when the client invokes a method on a proxy, Pyro a) packages the arguments and transfers them to the server b) invokes the method on the remote object c) packages the return value and transfers it to the client This kind of distributed programming is called Remote Procedure Call (RPC) in procedural languages, and Remote Method Invocation (RMI) in object-oriented languages.