Programming |
Nearly any language can be used for client/server programming; all that is required are a few simple functions for the communications services.
Python is a simple but powerful language that comes with many of the fundamental tools (TCP for connection-oriented and UDP for datagram services) needed for quickly programming networked applications. It is one of the simpler languages useful for course assignments.
Interactive mode
Python can be entered one statement at a time in IDLE shell window; useful for learning the language and debugging. Enter:
- 2+2
- a='He'
- a
- a=a+'llo'
- a
Editing and running programs
The editor is used to edit files and run Python programs.
def factorial(n) :
if n <= 1 : return 1
return n*factorial(n-1)
b = 16
Try creating a new file
- Open Python.
- In IDLE shell click: File | New Window
- Copy and Paste the above program.
- Click: File | Save | test.py
- Click:
- Run | Run Module
- b
- factorial( 5 )
Debugging in interactive mode
Interactive mode makes debugging programs much simpler (a dynamic debugger is part of the IDLE Shell). After running the module (i.e. Run Module) global variables can be examined and functions called.
Restarting - Restart a Python program by closing the Shell and running the module again.
Examining variables - Examine the global b variable by entering:
b
Calling functions - Call the factorial function with actual parameter of 5 by:
factorial( 5 )
TCP
Because TCP is a connection-oriented protocol, one process acts as a server accepting connections, another process acts as the client requesting the connection. Below are basic client and server scripts:
Client
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 8888))
s.send('Hello world')
data = s.recv(1024)
s.close()Server
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 8888))
s.listen(1)
conn, addr = s.accept()
data = conn.recv(1024)
conn.send(data)
conn.close()
Try
- Open Python in two windows: Start | Programs | Python | IDLE
- In each window:
- File | New
- Copy, paste and save the above files as:
- client.py
- server.py
- In the server window run by pressing F5
- In the client window run by pressing F5
- import socket - the TCP/IP socket library containing all the necessary function definitions.
- s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) - Constructs a socket and assigns to variable s.
- s.connect(('localhost', 8888)) - Client requests a connection with host 'localhost' on port 8888.
- s.bind(('', 8888)) - Server binds the script on host '' to port 8888.
- s.listen(1) - Server listens to accept 1 connection at a time.
- conn, addr = s.accept() - Server accepts connection request from a client; conn is the socket used for communication with client and addr the client's address.
- s.send('Hello world') - Send a string through the socket s.
- data = s.recv(1024) - Receive data through socket s, assign to variable data; a maximum of 1024 characters received at a time.
- s.close() - Close the connection on socket s.
# echoclient.py
import socket, sys
HOST = sys.argv[1] # The remote host
PORT = 8888 # Port used by the server
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True :
message = raw_input('Send:')
if not message : break
s.send(message)
data = s.recv(1024)
print 'Received', `data`
s.close() |
// echoserver.py
import socket
HOST = '' # Symbolic name
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while True:
data = conn.recv(1024)
if not data: break
conn.send(data)
conn.close() |
Try
- Open Python in two windows: Start | Programs | Python | IDLE
- In each window:
- File | New
- Copy, paste and save the above files as:
- echoclient.py
- echoserver.py
- In the echoserver window run by pressing F5
- In the echoclient window run by pressing F5
Data types
Python is provides very flexible data types useful for network programming:
Try
- Lists - A universal data type that can be heterogeneous; for example:
- L = [12, 'A', ['a nested list'], 3.14 ]
- L[2]
- L.append('another')
- Tuples - Similar to a C struc; used to group related data; represents heterogeneous data; example:
- T = ('A', [1,2,3])
- T[1]
- percept = (('A','Clean'), ('B','Dirty'))
- (x, y) = (('A','Clean'), ('B','Dirty'))
- x
- z = x + y
- z
- ( (a, b), (c, d) ) = (('A','Clean'), ('B','Dirty'))
- a
- d
- Dictionary - An associative array; consists of keys and value pairs; example:
- D = { 'B438' : 'networking', 'a list':[1,2,3], ('A', 'Clean'):5 }
- D['B438']
- D['a list']
- D[('A', 'Clean')]
Variables (dynamically typed)
Variables are dynamically typed by the value to which it is bound. In the program:
- A='A' binds variable A to a string; A can be used as a string; printing, concatenation, ...
- percepts = [] binds to an empty list; percepts can be used as a list; taking the head, inserting ...
- table is bound to a dictionary; allows look-ups on an index and other dictionary operations
Try
- Use the string concatenation operator on A, a string:
- A='abc'
- A=A+'1234'
- A
Bind L to a list and perform some list operations:
L = [4, 'Hi', ('A', 'Clean')]
L
L[2]
L.append('cow')
L
L.append(['a list', ['a nested list']])
L
Attempt to use string concatenation on lists:
A = A + L
Indentation
Used instead of { } to specify scope.
Control statements
Similar to C++.
x = 4
if x<5 :
print 'x<5'
x+=1
else :
print 'x>=y'Scope (static)
Any identifier defined outside a function is global; inside local.
Functions
Similar to C++. The factorial function; notice the indentation:
def factorial(n) :
if n <= 1 :
return 1
return factorial(n-1)*n
Try Write the power function for xn where n is a positive integer.
- Click File | New Window
- Click File | Save | power.py
- Type the function.
- Click Run | Run Shell | OK to save
- In Shell enter: power(4,3)
Example: echoclient and echoserver as functions
# echoclient.py
import socket, sys
def client( host, port) :
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((host, port))
while True :
message = raw_input('Send:')
if not message : return
s.send(message)
data = s.recv(1024)
print 'Received', `data`
s.close()client(sys.argv[1], 8888) |
// echoserver.py
import socket
def server( s ) :
conn, addr = s.accept()
print 'Connected by', addr
while True:
data = conn.recv(1024)
if not data: break
conn.send(data)
conn.close()s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.bind(('', 8888))
s.listen(1)
server( s ) |
Try
|
Exceptions
Exceptions allow a formal means of handling non-standard situations. For example, the following handles division by 0.
print '1'
try:
print '2'
x=9/0
print '3'
print x
except Exception:
print 'division by 0'
print '4'
print '5'
- try - Encloses the statements to be tried. No statements in the try are executed after an exception is raised.
- except - Encloses the statements executed only if an exception (in this case, any Exception) occurs in the statements immediately tried. After except statements are completed, execution continues with statements following the except.
The output is: 1, 2, division by 0, 4, 5