LECTURE 14 Introduction to Networking

advertisement
LECTURE 14
Introduction to Networking
NETWORKING IN PYTHON
Networking applications are a major use of the Python language.
Python supports low-level socket programming as provides high-level networking
libraries.
Today, we will start with the basics of sockets in Python.
We will then create a blackjack game server using the socket module.
SOCKETS
• A socket is one end-point of a two-way communication link between two programs
running on a network.
• Allows connections to be made and data to be transmitted in either direction.
Python’s socket module provides access to the BSD socket interface.
SOCKET BASICS
• Creating a socket
• socket.socket() returns a socket object.
• First argument is the address family.
• Second argument is the socket type.
• Creating an IPv4 TCP connection:
From socket import *
s = socket(AF_INET, SOCK_STREAM)
SOCKET BASICS
Address and Protocol families
• socket.AF_UNIX: Unix Domain Sockets (UDS) (Posix systems).
• socket.AF_INET: IPv4 Internet addressing (e.g. 10.1.1.5 and 127.0.0.1).
• socket.AF_INET6: IPv6 Internet addressing (128 bits).
Socket Types
• socket.SOCK_STREAM: Connection based stream (TCP).
• socket.SOCK_DGRAM: Datagrams (UDP).
• Other much less common options.
TCP CLIENT
s.connect(addr) makes a connection.
• address is a tuple (host, port).
s.send(string[, flags])
• Send string to remote socket.
• Returns number of bytes sent.
• Flags are available on man page for recv(2).
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.connect(("www.python.org",80)) # Connect
s.send("GET /index.html HTTP/1.0\n\n") # Send request
data = s.recv(10000) # Get response
s.close()
TCP CLIENT
s.recv(bufsize[, flags])
• bufsize is maximum number of bytes.
• Returns data received.
s.close() closes connection.
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.connect(("www.python.org",80)) # Connect
s.send("GET /index.html HTTP/1.0\n\n") # Send request
data = s.recv(10000) # Get response
s.close()
TCP SERVER
TCP Clients are easy – just create a connection and send and receive data as
needed.
TCP Servers must be listening and able to accept multiple connections at any time.
TCP SERVER
s.bind(address)
• address is a tuple (host, port).
• Binding to localhost makes the server
available only to the machine itself.
• Binding to socket.gethostname() makes
socket visible to outside.
• Bind to “” so the socket is reachable by
any address the machine has.
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
Note: low number ports usually reserved – use a 4 digit port number when testing.
TCP SERVER
s.listen(num)
• Listen for connections made to the
socket.
• Queue up as many as num connections
before connections are refused.
s.accept()
• Accept a connection.
• Returns (conn, address) where conn is a
new socket object and address is the
address bound to the other end of the
connection.
• Blocks until connection received.
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
TCP SERVER
s.listen(num)
• Listen for connections made to the
socket.
• Queue up as many as num connections
before connections are refused.
s.accept()
• Accept a connection.
• Returns (conn, address) where conn is a
new socket object and address is the
address bound to the other end of the
connection.
• Blocks until connection received.
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
New socket object is created for the specific client.
TCP CLIENTS AND SERVERS
Clients
• Issue connect() and then short sequences of send/receive data.
Servers
• bind(), listen(), loop: accept()  create client socket.
Useful utility functions:
socket.gethostbyname("www.python.org")  returns IP
socket.gethostbyaddr("82.94.237.218")  returns name
SEND AND RECV
Sending and receiving data is often done in stages – they are bound to the capacity
of the network buffers.
• s.send() returns number of bytes sent.
• s.recv() may receive fewer bytes than the specified max. Returns empty string when
connection is closed.
• s.sendall(string[, flags]) blocks until all data transmitted.
SOCKET OPTIONS
s.settimeout(value)
• Sets a timeout on blocking socket operations of value seconds.
s.setblocking(Flag)
• Sets whether socket operations should be blocking or non-blocking.
f = s.makefile()
• Can read and write socket as a file object f.
UDP SOCKETS
UDP does not require transmission handshaking or other setup, but offers lower
reliability of delivery.
UDP messages may be delivered out of order, multiple times, or not at all.
UDP Datagrams deliver higher performance.
Key new methods:
• s.sendto(string, address): sends string to address, returning number of bytes sent.
• s.recvfrom(buf): receive at most buf bytes of data from the socket. Returns (string,
address).
UDP CLIENT
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
msg = "Hello World”
s.sendto(msg,("server.com",10000))
data, addr = s.recvfrom(maxsize)
UDP SERVER
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("",10000))
while True:
data, addr = s.recvfrom(maxsize)
resp = "Get off my lawn!”
s.sendto(resp,addr)
No connection! – just receiving and
sending packets.
BACK TO TCP
Let’s go back to TCP
sockets for a while since
they’re more common.
What’s the problem with
this model?
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
BACK TO TCP
Let’s go back to TCP
sockets for a while since
they’re more common.
What’s the problem with
this model?
Every client will have to
wait for the previously
connection to close before
its own connection is made.
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
print "Received connection from", a
c.send("Hello %s\n" % a[0])
c.close()
THREADING
The threading module in the Python Standard Library allows us to implement threading –
running multiple operations concurrently within the same program space.
Simple usage:
t = threading.Thread(target=worker_function, args=(arg1, arg2))
Creates a thread t which will call worker_function with the arguments arg1 and arg2 when
the thread is started.
THREADED TCP SERVER
import threading
from socket import *
def handle_client(c):
... whatever ...
c.close()
return
s = socket(AF_INET,SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
t = threading.Thread(target=handle_client, args=(c,))
t.start()
FORKING TCP SERVER
import os
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("",9000))
s.listen(5)
while True:
c,a = s.accept()
if os.fork() == 0:
# Child process. Manage client
...
c.close()
os._exit(0)
else:
c.close()
EXAMPLE BLACKJACK SERVER
Check out threaded our threaded TCP server for playing Blackjack:
blackjack_server.py and card.py.
Download