Sei sulla pagina 1di 38

Version 8/02/17

Computer Networks II

application

Client-Server
transport

network

link Applications
physical

David.Villa@uclm.es
Contents
Introduction
UDP/TCP sockets
BSD sockets
Byte order
Address conversion
The socket class
UDP client and servers
TCP client and servers

2
Computer Networks II
Introduction
Transport layer is the core
of the whole protocol
hierarchy. upper
Transport
layers service user
It actually provides valuable
services to users and
applications. transport
Transport
network service
provider
link

physical

3
Computer Networks II
TCP / UDP sockets
Application that need to manage data transfers need an IP address (to
identify the destination host) and a port number (to identify a process).

The tuple (IP, port) is called socket.


A single flow is identified by a socket pair: (socket1, socket2)
TCP y UDP segments are encapsulated over IP datagrams.
IP header includes the IP address. TCP or UDP header include the port

TCP or UDP segment

header data

IP header IP payload
frame
frame payload frame tail
header

4
Computer Networks II
BSD Socket programming

A socket is a network connection endpoint.


Socket is the low-level API that provides the
transport layer services.
The original socket interface was part of the BSD
Unix, therefore they are often called BSD sockets.
On Unix-like (POSIX) systems the socket API is
implemented as system calls. That is very similar to
conventional files: open/read/write

5
Computer Networks II
Sockets :: flavors
Apart from STREAM y
Application
Application DGRAM sockets it is
Stream Datagram raw common to have other
sockets sockets sockets
sockets flavors as RAW
or UNIX
The RAW sockets
TCP
TCP UDP
UDP usually require special
IP
IP
privileges

underlying
underlying protocols
protocols

6
Computer Networks II
Byte order
The computer architecture design may decide
among two byte order conventions: big-endian
(Motorola) or little endian (Intel)
This is also a network protocol characteristic.
TCP/IP stack protocols use big-endian (on-wire
endianess)
Operations to byte order conversion among host
and network are required:
htons() - host to network short (16 bits)
htonl() - host to network long (32 bits)
ntohs() - network to host short
ntohl() - network to host long
http://en.wikipedia.org/wiki/Endianness

7
Computer Networks II
Address conversion

Functions to convert among binary IP address and


their ASCII representation (integers with dots) are also
available:
inet_aton() - ASCII to binary format
inet_ntoa() - binary format to ASCII

>>> socket.inet_aton('192.168.0.1')
b'\xc0\xa8\x00\x01'
>>> struct.unpack('I', _))[0]
16820416
>>> bin(_)
'0b1000000001010100011000000'

8
Computer Networks II
Sockets
The BSD socket API, as all other system calls, is
implemented as C functions.
For simplicity, but without loss of generality, we will
use the Python socket library. It is just a wrapper to
the C system calls.

9
Computer Networks II
Socket class
Python sockets are objects. Class constructor is: :
socket(family, type, [proto])
familiy: AF_INET, AF_INET6, AF_UNIX, AF_PACKET, etc
type: SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
proto: When a given type allows several protocols.
For IPv4: AF_INET with
SOCK_DGRAM for UDP,
SOCK_STREAM for TCP.
SOCK_RAW allows to build packet directly over the link layer.

10
Computer Networks II
Socket class
bind(address) Bind the socket with the given address.
address: The address format depends on the specific socket family.
When family is AF_INET address is a duple (host, port).
connect(address)
If we use STREAM, this connects the local socket to the remote one in the
given address. If we use DGRAM this specify the source and destination
default address.
listen(backlog)
backlog specifies how many clients at maximum are waiting for
connection. The following connections will be rejected. It is applicable to
STREAM sockets only.

11
Computer Networks II
Socket class
accept() - Accepts an incoming connection. STREAM only.
It returns a duple (conn, address):
conn: is the child socket to manage the connection to the remote
client.
address: Lis the remote endpoint address (the client)
send(data) it sends data to the remote socket. If it is a DGRAM
socket, the data is sent to the default destination address specified by
connect(). It returns how many bytes are written.
recv(size) - size is the amount of bytes to read. It returns how
many bytes are actually received.

12
Computer Networks II
Socket class
sendto(data, address) send data to the socket given by
address. For DGRAM sockets only.
recvfrom(size) - size is the amount of bytes to read. It returns a
duple (data, address):
data: is the received data
address: is the socket sending this data.

Only for DGRAM sockets.


shutdown(how) close a running connection (STREAM) in the given
way: read, write, both.
close() close the running connection and free allocated resources

13
Computer Networks II
Sockets as files
The socket C API provides read() y write() functions that are full
compliant with the file API counterpart
In Python, socket class has not that method, and no other functions
are directly applicable, as flush().
However, it provides methods to get an associated file handler .
fileno() returns the file descriptor (as integer) related to the
socket.
makefile() returns a file object associated to the socket.
The socket module provides the fromfd()function also. It returns
the socket associated to a file.

14
Computer Networks II
UDP client/server interaction
UDP server UDP client

socket() socket()

bind()

sendto()

recvfrom()

processing recvfrom()

sendto()
close()

15
Computer Networks II
upper service with UDP
UDP server

socket() UDP client

bind() socket()

hello
msg = recvfrom() sendto()
MSG = msg.upper()
HELLO
sendto(MSG) recvfrom()

close()

16
Computer Networks II
UDP client Full
listing

#!/usr/bin/python
"Usage: %s <server> <port>"

from sys import argv, exit


from socket import *

if len(argv) != 3:
print(__doc__ % argv[0])
exit(1)

sock = socket(AF_INET, SOCK_DGRAM)

while 1:
data = input().encode()
if not data: break # ends with ''

sock.sendto(data, (argv[1], int(argv[2])))


msg, server = sock.recvfrom(1024)
print("Reply is '%s'" % msg.decode())

sock.close()

17
Computer Networks II
Basic UDP server Full
Synchronous listing

if len(argv) != 2:
#!/usr/bin/python print(__doc__ % argv[0])
"Usage: %s <port>" exit(1)

from sys import argv, exit sock = socket(AF_INET, SOCK_DGRAM)


from socket import * sock.bind(('', int(argv[1])))
import time
n = 0
def handle(sock, msg, client, n): while 1:
print('New request', n, client) msg, client = sock.recvfrom(1024)
time.sleep(1) # some job n += 1
sock.sendto(msg.upper(),client) handle(sock, msg, client, n)

18
Computer Networks II
Running server and client

upper$ ./UDP_server.py 2000


New request 1 ('127.0.0.1', 41285)

upper$ ./UDP_client.py localhost 2000


hi
Reply is 'HI'
bye
Reply is 'BYE'

(Control-D)

19
Computer Networks II
UDP datagram capture
$ cat 20-tigers | ./UDP_client.py localhost 2000
Reply is 'TWENTY'
Reply is 'TINY'
Reply is 'TIGERS'
Reply is 'TAKE'
Reply is 'TWO'
Reply is 'TAXIS'
Reply is 'TO'
Reply is 'TOWN'

$ tshark -i lo -f "udp port 2000"


Capturing on 'Loopback'
1 0.000000 127.0.0.1 -> 127.0.0.1 UDP 48 Source port: 50162 Destination port: 2000
2 1.001407 127.0.0.1 -> 127.0.0.1 UDP 48 Source port: 2000 Destination port: 50162
3 1.001805 127.0.0.1 -> 127.0.0.1 UDP 46 Source port: 50162 Destination port: 2000
4 2.003094 127.0.0.1 -> 127.0.0.1 UDP 46 Source port: 2000 Destination port: 50162
5 2.003425 127.0.0.1 -> 127.0.0.1 UDP 48 Source port: 50162 Destination port: 2000
6 3.004717 127.0.0.1 -> 127.0.0.1 UDP 48 Source port: 2000 Destination port: 50162
7 3.005048 127.0.0.1 -> 127.0.0.1 UDP 46 Source port: 50162 Destination port: 2000
8 4.006338 127.0.0.1 -> 127.0.0.1 UDP 46 Source port: 2000 Destination port: 50162
9 4.006795 127.0.0.1 -> 127.0.0.1 UDP 45 Source port: 50162 Destination port: 2000
10 5.008152 127.0.0.1 -> 127.0.0.1 UDP 45 Source port: 2000 Destination port: 50162
11 5.008478 127.0.0.1 -> 127.0.0.1 UDP 47 Source port: 50162 Destination port: 2000
12 6.009747 127.0.0.1 -> 127.0.0.1 UDP 47 Source port: 2000 Destination port: 50162
13 6.010120 127.0.0.1 -> 127.0.0.1 UDP 44 Source port: 50162 Destination port: 2000
14 7.011391 127.0.0.1 -> 127.0.0.1 UDP 44 Source port: 2000 Destination port: 50162
15 7.011723 127.0.0.1 -> 127.0.0.1 UDP 46 Source port: 50162 Destination port: 2000
16 8.013006 127.0.0.1 -> 127.0.0.1 UDP 46 Source port: 2000 Destination port: 50162
20
Computer Networks II
UDP server Full
SocketServer.UDPServer listing

"Usage: %s <port>"

from sys import argv, exit


from socketserver import *
import time

class UpperHandler(DatagramRequestHandler):
def handle(self):
print('New request:', self.client_address)
msg = self.rfile.read()
time.sleep(1)
self.wfile.write(msg.upper())

if len(argv) != 2:
print(__doc__ % argv[0])
else:
UDPServer(('', int(argv[1])), UpperHandler).serve_forever()

21
Computer Networks II
UDP server Full
SocketServer.ForkingUDPServer listing

"Usage: %s <port>"

from sys import argv, exit


from socketserver import *
import time

class UpperHandler(DatagramRequestHandler):
def handle(self):
print('New request:', self.client_address)
msg = self.rfile.read()
time.sleep(1)
self.wfile.write(msg.upper())

if len(argv) != 2:
print(__doc__ % argv[0])
else:
ForkingUDPServer(('', int(argv[1])), UpperHandler).serve_forever()

22
Computer Networks II
TCP client/server interaction
TCP master server

socket() TCP client

bind() socket()

listen() connect()

accept() send()
TCP child server

recv()

recv()
process, thread close()
creation or job
asynchronous
send()
management

close()
23
Computer Networks II
TCP client Full
listing

sock = socket(AF_INET, SOCK_STREAM)


sock.connect((argv[1],int(argv[2])))

#!/usr/bin/python
while 1:
"Usage: %s <server> <port>" data = input().encode()
if not data: break # ends with ''
from sys import argv, exit sent = sock.sendall(data)
from socket import *
msg = bytes()
if len(argv) != 3: while len(msg) < sent:
print(__doc__ % argv[0]) msg += sock.recv(32)
exit(1)
print("Reply is '%s'" % msg)

sock.close()

24
Computer Networks II
Basic TCP server Full
listing

#!/usr/bin/python if len(argv) != 2:
"Usage: %s <port>" print(__doc__ % argv[0])
exit(1)
from sys import argv, exit
from socket import * sock = socket(AF_INET, SOCK_STREAM)
import time sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.bind(('', int(argv[1])))
def handle(sock, client): sock.listen(5)
print('Client connected:', client)
while 1: while 1:
data = sock.recv(32) child_sock, client = sock.accept()
if not data: break handle(child_sock, client)
time.sleep(1) # some job
sock.sendall(data.upper())

sock.close()

25
Computer Networks II
netcat
It's a powerfull generic network tool. Several available
implementations.
We recommend using ncat. . .
\`-"'"-'/
It can be usel like: } 6 6 {
==. Y ,==
UDP server, client. /
/^^^\ .
\ )
TCP server, client.

( )-( )/ _
-""---""--- /
/ Ncat \_/
TCP and UDP port redirection. ( ____
\_.=|____E
HTTP and SOCKS proxy.
...

26
Computer Networks II
TCP server Full
process per conection (I) listing

#!/usr/bin/python
def collect_children(children):
"Usage: %s <port>"
while children:
if len(children) < MAX_CHILDREN:
from sys import argv, exit
opts = os.WNOHANG
import socket
else:
import os, time
opts = 0

MAX_CHILDREN = 40
pid, status = os.waitpid(0, opts)
if not pid: break
def handle(sock, client, n):
children.remove(pid)
print('Client connected', n, client)
while 1:
data = sock.recv(32)
if not data: break
time.sleep(1) # some job
sock.sendall(data.upper())
sock.close()

27
Computer Networks II
TCP server
process per conection (II)

if len(argv) != 2:
print(__doc__ % argv[0])
exit(1)

sock = socket.socket(socket.AF_INET, while 1:


socket.SOCK_STREAM) child_sock, client = sock.accept()
sock.bind(('', int(argv[1]))) n += 1
sock.listen(5)
collect_children(children)
n = 0 pid = os.fork()
children = []
if pid:
children.append(pid)
else:
handle(child_sock, client, n)
exit()

28
Computer Networks II
TCP server Full
thread per conection (I) listing

from sys import argv, exit


from socket import *
import _thread, time

def handle(sock, client, n): if len(argv) != 2:

print('Client connected', n, client) print(__doc__ % argv[0])

while 1: exit(1)

data = sock.recv(32)
sock= socket(AF_INET, SOCK_STREAM)
if not data: break
sock.bind(('', int(argv[1])))
time.sleep(1) # some job
sock.listen(5)
sock.sendall(data.upper())

n = 0
sock.close() while 1:
child_sock, client = sock.accept()
n += 1
_thread.start_new_thread(
handle,
(child_sock, client, n))

29
Computer Networks II
Asynchronous TCP server Full
select() listing

from sys import argv, exit def ParentHandler(s):


from socket import * child_sock, client = s.accept()
import select, time socks.append(child_sock)
print('Client connected:', client)
def ChildHandler(s):
ss = socket(AF_INET, SOCK_STREAM)
data = s.recv(32)
ss.bind(('', int(argv[1])))
if not data:
ss.listen(5)
s.close()
socks.remove(s)
socks = [ss]
return
while 1:
time.sleep(1) # some job
rd = select.select(socks, [], [])[0]
s.sendall(data.upper())

for i in rd:
if i == ss:
ParentHandler(i)
else:
ChildHandler(i)

30
Computer Networks II
TCP server Full
SocketServer.TCPServer listing

from sys import argv, exit


from socketserver import *
import time

class UpperHandler(StreamRequestHandler):
def handle(self):
print('Client connected:', self.client_address)
while 1:
data = sock.recv(32)
if not data: break
time.sleep(1) # some job
sock.sendall(data.upper())
self.request.close()

if len(argv) != 2:
print(__doc__ % argv[0])
else:
server = TCPServer(('',int(argv[1])), UpperHandler)
server.serve_forever()

31
Computer Networks II
TCP server Full
SocketServer.ForkingTCPServer listing

from sys import argv, exit


from socketserver import *
import time

class UpperHandler(StreamRequestHandler):
def handle(self):
print('Client connected:', self.client_address)
while 1:
data = sock.recv(32)
if not data: break
time.sleep(1) # some job
sock.sendall(data.upper())

self.request.close()

if len(argv) != 2:
print(__doc__ % argv[0])
else:
server = ForkingTCPServer(('',int(argv[1])), UpperHandler)
server.serve_forever()

32
Computer Networks II
TCP server Full
SocketServer.ThreadingTCPServer listing

from sys import argv, exit


from socketserver import *
import time

class UpperHandler(StreamRequestHandler):
def handle(self):
print('Client connected:', self.client_address)
while 1:
data = sock.recv(32)
if not data: break
time.sleep(1) # some job
sock.sendall(data.upper())
self.request.close()

if len(argv) != 2:
print(__doc__ % argv[0])
else:
server = ThreadingTCPServer(('',int(argv[1])), UpperHandler)
server.serve_forever()

33
Computer Networks II
TCP server Full
module asyncore listing

#!/usr/bin/python class ChildHandler(asyncore.dispatcher):


"Usage: %s <port>" def __init__(self, sock):
asyncore.dispatcher.__init__(self, sock)
from sys import argv, exit self.buffer = bytes()
from socket import *
import asyncore, time def handle_read(self):
self.buffer += self.recv(32)
time.sleep(JOB) # some job

def writable(self):
return (len(self.buffer) > 0)

def handle_write(self):
sent = self.send(self.buffer.upper())
self.buffer = self.buffer[sent:]

def handle_close(self):
self.close()

34
Computer Networks II
TCP server
module asyncore (II)

class ParentHandler(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(AF_INET, SOCK_STREAM)
self.set_reuse_addr()
self.bind(('', int(argv[1])))
self.listen(5)

def handle_accept(self):
child_sock, client = self.accept()
print('Client connected', client)
ChildHandler(child_sock)

ParentHandler()
asyncore.loop()

35
Computer Networks II
Process server
A process server (superserver) is a special program that
listen on many ports (TCP and UDP) at time. It is useful
for sporadic services.
When a incoming connection occurs in any of that ports,
the superserver instance a preconfigured program
(usually in a child process) to manage the related
service.
In GNU/Linux systems the common superserver is
inetd and may be configured with file
/etc/inetd.conf

36
Computer Networks II
Process server

Exercise

Using standard Python, write a process server that internally


provide servers for echo, daytime, time y discard
protocols, both TCP and UDP. And it must be able to call
external standard servers for ftp, tftp y telnet.

37
Computer Networks II
References
We recommend to students read the next materials (at least) to improve knowledge
and understanding for this topic concepts:
A.S. Tanenbaum. Computer Networks. Pearson, Fourth edition, 2003.
Chapter 6. Sections 1 - 5.10
CISCO Systems. Inc. Gua del primer ao. CCNA 1 y 2. Cisco Press, 2003.
Chapters 9 y 19
e-learning CISCO CCNA Exploration
Module 4

Tip
All listings in this topic are available for download at:
https://bitbucket.org/arco_group/upper
38
Computer Networks II

Potrebbero piacerti anche