Sei sulla pagina 1di 20

NP 02 UDP

What for?
to be doing any programming on an IP
network
understanding of what is happening down at
these low levels will serve you very well :
fetching pages from a web server
sending complicated queries to an industrial
database.

Ex: DNS, real-time audio and video chat, and


DHCP

Watch out!!
The deployment of UDP is even rather
dangerous for the general health of the IP
network.

Addresses and Port Numbers


IP?
Port?
0 to 65,536
Ex: 192.168.1.9 : 53, 192.168.1.30 : 44137

The address 127.0.0.1 is how machines can


connect to themselves.

Port Number Ranges


So the UDP scheme is really quite simple;
IP address and port are all that is necessary to
direct a packet to its destination.

How do clients learn the IP addresses and


ports to which they should connect?
Convention
automatic configuration:
Manual configuration

When making decisions about defining port


numbers
Well-Known Ports (01023)
Registered Ports (102449151)
The remaining port numbers (4915265535) are
free for any use.

Instance method

sock.bind( (adrs, port) ) Bind the socket to the address and port
sock.accept() Return a client socket (with peer address information)
sock.listen(backlog) Place the socket into the listening state, able topend
backlog outstanding connection requests
sock.connect( (adrs, port) ) Connect the socket to the defined host and port
sock.recv( buflen[, flags] ) Receive data from the socket, up to buflen bytes
sock.recvfrom( buflen[, flags] ) Receive data from the socket, up to buflen
bytes, returning also the remote host and port from which the data came
sock.send( data[, flags] ) Send the data through the socket
sock.sendto( data[, flags], addr ) Send the data through the socket
sock.close() Close the socket
sock.getsockopt( lvl, optname ) Get the value for the specified socket option
sock.setsockopt( lvl, optname, val ) Set the value for the specified socket
option

ask where the


Domain Name Service lives
>>> import socket
>>> socket.getservbyname('domain')
Open /etc/services

# WELL KNOWN PORT NUMBERS


#
rtmp
1/ddp #Routing Table Maintenance Protocol
tcpmux
1/udp # TCP Port Service Multiplexer
tcpmux
1/tcp # TCP Port Service Multiplexer

Sockets
Python exposes the normal POSIX calls for raw
UDP and TCP connections rather than trying to
invent any of its own
And the normal POSIX networking calls operate
around a central concept called a socket.
Sockets provide the same idea for the networking
realm:
when you ask for access to a line of communication
you create one of these abstract socket objects and
then ask for it to be bound to the port you want to
use.

It is time to show you source code.


import socket, sys
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
MAX = 65535
PORT = 1060

server

client

if sys.argv[1:] == ['server']:
s.bind(('127.0.0.1', PORT))
print 'Listening at', s.getsockname()
while True:
data, address = s.recvfrom(MAX)
print 'The Client ar', address, 'sys', repr(data)
s.sendto('your data was %d bytes' % len(data), address)
elif sys.argv[1:] == ['client']:
print 'Address before sending:', s.getsockname()
s.sendto(' hi this is my message', ('127.0.0.1', PORT))
print 'Address after sending', s.getsockname()
data, address = s.recvfrom(MAX)
print 'The server', address, 'says', repr(data)

Unreliability, Backoff,
Blocking, Timeouts
So how do we write a real UDP client, one that
has to deal with the fact that packets might be
lost?
This difficult choice is necessary because there is
generally no way for the client to distinguish
between three quite different events:
The reply is taking a long time to come back, but will
soon arrive.
The reply will never arrive because it, or the request,
was lost.
The server is down and is not replying to anyone.

It is time to show you source code.

server

client

if 2 <= len(sys.argv) <= 3 and sys.argv[1] == 'server':


interface = sys.argv[2] if len(sys.argv) > 2 else ''
s.bind((interface, PORT))
print 'Listening at', s.getsockname()
while True:
data, address = s.recvfrom(MAX)
if random.randint(0,1):
print 'the client at', address, 'says:', repr(data)
s.sendto('your data was %d bytes' % len(data), address)
else:
print 'Pretending to drop packet from', address
elif len(sys.argv) == 3 and sys.argv[1] == 'client':
hostname = sys.argv[2]
s.connect((hostname, PORT))
print 'Client socket name is', s.getsockname()
delay = 0.1
while True:
s.send('This is another message')
print 'waiting up to', delay, 'seconds for a reply'
s.settimeout(delay)

Connecting UDP Sockets


Running udp_local.py client
import socket, sys
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
MAX = 65535
PORT = 1060
print 'Address before sending:', s.getsockname()
s.sendto(' hi this is my message', ('127.0.0.1', PORT))
print 'Address after sending', s.getsockname()
data, address = s.recvfrom(MAX)
print 'The server', address, 'says', repr(data)

>>> import socket


>>> s = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)
>>> s.sendto('Fake reply', ('127.0.0.1', port))

Binding to Interface

Bind()
Ethernet
Running udp_remote.py server
Running udp_remote.py server someip
Running udp_remote.py client someip

UDP Fragmentation
UDP lets you, as a user, send raw network packets
to which just a little bit of information
your Ethernet or wireless card can only handle
packets of around 1,500 bytes instead
How to send packet over it(example 64 kb)
The actual truth is that IP sends small UDP
packets as single packets on the wire, but splits
up larger UDP packets into several small physical
packets
MTU

Create big_sender.py
Running big_sender.py somename

Socket option
Python calls getattr() and setattr()
Many options are specific to particular
operating systems
SO_BROADCAST:
SO_DONTROUTE:
SO_TYPE

broadcast
Broadcast vs Multicast
Create udp_broadcast.py

import socket, sys


s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
MAX = 65535
PORT = 1060
if 2 <=len(sys.argv) <= 3 and sys.argv[1] == 'server':
s.bind(( ', PORT))
print 'Listening for broadcast at', s.getsockname()
while True:
data, address = s.recvfrom(MAX)
print 'the client at %r says: %r' % (address, data)
elif len(sys.argv) == 3 and sys.argv[1] == 'client':
network = sys.argv[2]
s.sendto('broadcast message!', (network, PORT))
else:
print >>sys.stdrr, 'usage: udp_broadcast.py server'
print >>sys.stdrr, ' or: udp_broadcast.py client <host>'
sys.exit(2)

Potrebbero piacerti anche