NETWORK PROGRAMMING USING PYTHON
C U A U H T E M O C C A R B A J A L I T E S M C E M A P R I L 0 6 , 2 0 1 3
1
NETWORK PROGRAMMING USING PYTHON C U A U H T E M O C C A R B A J A - - PowerPoint PPT Presentation
NETWORK PROGRAMMING USING PYTHON C U A U H T E M O C C A R B A J A L I T E S M C E M A P R I L 0 6 , 2 0 1 3 1 NETWORK OVERVIEW Network Overview Python provides a wide assortment of network support Low-level programming with
C U A U H T E M O C C A R B A J A L I T E S M C E M A P R I L 0 6 , 2 0 1 3
1
protocol).
Programming using Python)
2
can communicate,
the Internet,
CPU, and of course the network.
are themselves each designed with an elaborate ability to share a single physical medium among many different devices that want to communicate.
“packet.”
bytes, which is transmitted as a single unit between network devices.
delivered.
3
the Internet-connected computers in the entire world, and
Internet to the other.
able to connect a host anywhere without ever knowing which maze of network devices each packet is traversing on its journey.
low level that it sees the Internet Protocol itself in action, but in many situations, it is helpful to at least know how it works.
4
destination through a sequence of routers
5
layer
data from the layer above …
PROTOCOL DATA
DATA Upper layer Lower layer HDR
6
UDP TCP Data Link Physical Applications
The Hourglass Model Narrow Waist
FTP HTTP TFTP NV TCP UDP IP NET1 NET2 NETn …
7
W W W P C
8
http://www.seecs.edu.pk
9
How to send this request to Webserver? Which application at webserver must process this packet?
GET / HTML/1.1
10
11
W W W D N S
12
W W W D N S Request
13
W W W D N S
Reply
14
Source Port | Destination Port | GET / HTML/1.1 > 1024 | 80 |
15
Source IP | Destination IP | Source Port | Destination Port | GET / HTML/1.1 202.125.157.150 | 202.125.157.196 | > 1024 | 80 |
*Assuming /24 subnet mask (to be explained later)
16
17
W W W D N S Request
Request
18
W W W D N S
Reply
19
Source IP | Destination IP | Source Port | Destination Port | GET / HTML/1.1 202.125.157.150 | 202.125.157.196 | > 1024 | 80 | Payload Source MAC address | Destination MAC address FCS
20
GET / HTML/1.1 Source MAC address | Destination MAC address 23:34:aa:bb:cc:dd | 12:34:aa:bb:cc:dd FCS Payload Payload Source Port | Destination Port > 1024 | 80 Payload Payload Source IP | Destination IP 202.125.157.150 | 202.125.157.196 Payload
21
W W W D N S
Request
22
W W W D N S
Reply
23
face a fundamental question:
best be constructed from individual, unordered, and unreliable network packages?
instead appears to offer an ordered and reliable stream of bytes, so that their clients and servers can converse as though talking to a local pipe?
Transmission Control Protocol, which offers ordered and reliable data streams between IP applications.
responses, and simple clients that will not be annoyed if a request gets lost and they have to repeat it, choose UDP, the User Datagram Protocol.
24
25
26
27
28
available in a “TCP/IP” environment Telnet SSH SMTP FTP NFS DNS SNMP TCP UDP IP
Ethernet, Token Ring, RS232, IEEE 802.3, HDLC, Frame Relay, Satellite, Wireless Links, Wet String
Application Host-to-host Internetwork Subnetwork
29
30
http://tech.ebu.ch/docs/techreview/trev_292-kozamernik.pdf
31
"sockets"
a file.
connections.
create a socket object.
32
A T N DATA DL CRC Application Host-to-host Internetwork Subnetwork Socket API
33
to a port (by the server).
the OS.
common protocols
FTP Port 20 Telnet Port 23 SMTP (Mail) Port 25 HTTP (WWW) Port 80
SSH Port 22 DNS Port 53
34
number, and starts listening.
(through the above port).
listen for more clients).
35
Socket call Write call Read call Close calls
Bind call Listen call Accept call
Connect call
36
request response
Connection establishment End-of-file notification
37
38
socket() bind() recvfrom() sendto() [blocked] SERVER socket() bind() recvfrom() [blocked] sendto() CLIENT UDP
from socket import socket, AF_INET, SOCK_DGRAM s = socket(AF_INET, SOCK_DGRAM) s.bind(('127.0.0.1', 11111)) while 1: data, addr = s.recvfrom(1024) print "Connection from", addr s.sendto(data.upper(), addr)
Note that the bind() argument is a two-element tuple of address and port number ex3.py
40
from socket import socket, AF_INET, SOCK_DGRAM s = socket(AF_INET, SOCK_DGRAM) s.bind(('127.0.0.1', 0)) # OS chooses port print "using", s.getsockname() server = ('127.0.0.1', 11111) s.sendto("MixedCaseString", server) data, addr = s.recvfrom(1024) print "received", data, "from", addr s.close()
ex4.py
41
provided
used by the service?
listening?
42
http://www.youtube.com/watch?v=aczPDGC3f8U
43
def spew(msg, host='localhost', port=PORT): s = socket.socket((socket.AF_INET,socket.SOCK_DGRAM)) s.bind(('', 0)) while msg: s.sendto(msg[:BUFSIZE], (host, port)) msg = msg[BUFSIZE:]
44
def bucket(port=PORT, logfile=None): s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) s.bind(('', port)) print 'waiting on port: %s' % port while 1: try: data, addr = s.recvfrom(BUFSIZE) print `data`[1:-1] except socket.error, msg: print msg
45
functionality in a single module
46
socket() bind() listen() accept() read() write() [blocked] socket() connect() write() read() [blocked] [blocked] Server Client
When interaction is over, server loops to accept a new connection
TCP
47
# Time server program from socket import * import time s = socket(AF_INET, SOCK_STREAM) # Create TCP socket s.bind(("",8888)) # Bind to port 8888 s.listen(5) # Start listening while 1: client,addr = s.accept() # Wait for a connection print "Got a connection from ", addr client.send(time.ctime(time.time())) # Send time back client.close()
ex1.py
48
using send() and recv().
# Time client program from socket import * s = socket(AF_INET,SOCK_STREAM) # Create TCP socket s.connect(("127.0.0.1",8888)) # Connect to server tm = s.recv(1024) # Receive up to 1024 bytes s.close() # Close connection print "The time is", tm ex2.py
49
Stream socket (TCP)
Datagram socket (UDP)
50
# Accept a new connection
# Bind to an address and port
# Close the socket
# Connect to remote socket
# Return integer file descriptor
# Get name of remote machine
# Get socket address as (ipaddr,port)
# Get socket options
# Start listening for connections
# Turn socket into a file object
# Receive data
# Receive data (UDP)
# Send data
# Send packet (UDP)
# Set blocking or nonblocking mode
# Set socket options
# Shutdown one or both halves of connection
51
socket.ntohl(x) # Convert 32-bit integer to host socket.ntohs(x) # Convert 16-bit integer to host order socket.htonl(x) # Convert 32-bit integer to network order socket.htons(x) # Convert 16-bit integer to network order
# Convert addresses between dotted-quad string # format to 32-bit packed binary format socket.inet_ntoa(packed) # Convert a 32-bit packed IPv4 address (a string # four characters in length) to its standard dotted- # quad string representation
52
53
54
provided
input, for example)?
55
56
57
SO_*, MSG_*, IP_* and so on
58
59
library
necessary to create networked clients and servers.
behalf.
another difference is that now we will be writing our applications using classes.
data and logically direct functionality to the right places.
system (including the sending and receiving of messages)
60
Class Description BaseServer Contains core server functionality and hooks for mix-in classes; used only for derivation so you will not create instances of this class; use TCPServer or UDPServer instead TCPServer/ UDPServer Basic networked synchronous TCP/UDP server UnixStreamServer/ UnixDatagramServer Basic file-based synchronous TCP/UDP server ForkingMixIn/Threading MixIn Core forking or threading functionality; used only as mix-in classes with one of the server classes to achieve some asynchronicity; you will not instantiate this class directly ForkingTCPServer/ ForkingUDPServer Combination of ForkingMixIn and TCPServer/UDPServer ThreadingTCPServer/ ThreadingUDPServer Combination of ThreadingMixIn and TCPServer/UDPServer BaseRequestHandler Contains core functionality for handling service requests; used
StreamRequest Handler or DatagramRequestHandler instead StreamRequestHandler/ DatagramRequestHandler Implement service handler for TCP/UDP servers
61
62
63
and handler class.
StreamRequestHandler and override its handle() method, which is called when an incoming message is received from a client. import SocketServer import time # This class actually implements the server functionality class MyRequestHandler(SocketServer.StreamRequestHandler): def handle(self): print '...connected from:', self.client_address self.wfile.write('[%s] %s' % (ctime(), self.rfile.readline())) # Create the server server = SocketServer.TCPServer(("",21567), MyRequestHandler) print 'waiting for connection...' server.serve_forever()
tsTservSS.py
64
like objects, so we will use readline() to get the client message and write() to send a string back to the client.
from socket import * BUFSIZ = 1024 while True: tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(('localhost', 21567)) data = raw_input('> ') if not data: break tcpCliSock.send('%s\r\n' % data) data = tcpCliSock.recv(BUFSIZ) if not data: break print data.strip() tcpCliSock.close()
tsTclntSS.py
65
features
to serve specific protocols
handle() method, to handle requests
66
handler-class as arguments: SocketServer.UDPServer(myaddr, MyHandler)
handler instance by calling the handler-class*
(UDP) or a complete client session (TCP)
* In Python you instantiate a class by calling it like a function
67
session
68
libraries
69
# udps1.py import SocketServer class UCHandler(SocketServer.BaseRequestHandler): def handle(self): remote = self.client_address data, skt = self.request print data skt.sendto(data.upper(), remote) myaddr = ('127.0.0.1', 2345) myserver = SocketServer.UDPServer(myaddr, UCHandler) myserver.serve_forever()
Change this function to alter server's functionality
70
# udpc1.py from socket import socket, AF_INET, SOCK_DGRAM srvaddr = ('127.0.0.1', 2345) data = raw_input("Send: ") s = socket(AF_INET, SOCK_DGRAM) s.bind(('', 0)) s.sendto(data, srvaddr) data, addr = s.recvfrom(1024) print "Recv:", data
Hangs if no response
71
# tcps1.py import SocketServer class UCHandler(SocketServer.BaseRequestHandler): def handle(self): print "Connected:", self.client_address while 1: data = self.request.recv(1024) if data == "\r\n": break print data[:-2] self.request.send(data.upper()) myaddr = ('127.0.0.1', 2345) myserver = SocketServer.TCPServer(myaddr, UCHandler) myserver.serve_forever()
Change this function to alter server's functionality
72
# tcpc1.py from socket import socket, AF_INET, SOCK_STREAM srvaddr = ('127.0.0.1', 2345) s = socket(AF_INET, SOCK_STREAM) s.connect(srvaddr) while 1: data = raw_input("Send: ") s.send(data + "\r\n") if data == "": break data = s.recv(1024) print data[:-2] # Avoids doubling-up the newline s.close()
73
servers with the same clients you used before
server?
74
75
accept() read() write() [blocked] [blocked] Client connection
Forked server process or thread runs independently
Remote Client Process
Server creates a new thread or forks a new process to handle each request
76
myserver = SocketServer.TCPServer( myaddr, UCHandler)
myserver = SocketServer.ThreadingTCPServer( myaddr, UCHandler)
myserver = SocketServer.ForkingTCPServer( myaddr, UCHandler)
77
(from SocketServer.py):
class ForkingUDPServer(ForkingMixIn, UDPServer): pass class ForkingTCPServer(ForkingMixIn, TCPServer): pass class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
78
79
required (UDP often message-response)
Windows (like you care … ☺)
80