Sunteți pe pagina 1din 24

Communication par sockets

Olivier Dalle
Universit de Nice - Sophia Antipolis
http://deptinfo.unice.fr/
Daprs le cours original de
Sacha Krakowiak
Universit Joseph Fourier
Projet Sardes (INRIA et IMAG-LSR)
http://sardes.inrialpes.fr/~krakowia

Rappel : le rseau vu de lutilisateur (1)

Client

Serveur

(demande un service)

(fournit un service)

Le schma client-serveur a t vu en TD pour des processus sur une mme


machine. Ce schma se transpose un rseau, o les processus client et
serveur sont sur des machines diffrentes.
Pour le client, un service est souvent dsign par un nom symbolique (par
exemple mail, http://..., telnet, etc.). Ce nom doit tre converti en une
adresse interprtable par les protocoles du rseau.
La conversion dun nom symbolique (par ex. http://www.google.com) en
une adresse IP (216.239.39.99) est la charge du service DNS
O. Dalle (cours original de S. Krakowiak)

7-2

Le rseau vu de lutilisateur (2)


port 80
connexion

Client
(demande un service)

adresse IP :
216.239.39.99

Serveur
(fournit un service)

En fait, ladresse IP du serveur ne suffit pas, car le serveur (machine physique)


peut comporter diffrents services; il faut prciser le service demand au
moyen dun numro de port, qui permet datteindre un processus particulier sur
la machine serveur.
Un numro de port comprend 16 bits (0 65 535). Les numros de 0 1023
sont rservs, par convention, des services spcifiques. Exemples :
7 : echo
80 : serveur web
O. Dalle (cours original de S. Krakowiak)

23 : telnet (connexion distance)


25 : mail
7-3

Le rseau vu de lutilisateur (3)

194.199.25.39:34231
socket
client

Client
(demande un service)

socket
serveur

216.239.39.99:45321
adresse IP

n de port

Serveur
(fournit un service)

Pour programmer une application client-serveur, il est commode dutiliser les


sockets (disponibles en particulier sous Unix). Les sockets fournissent une
interface qui permet dutiliser facilement les protocoles de transport TCP et UDP
Une socket est simplement un moyen de dsigner lextrmit dune connexion,
ct metteur ou rcepteur, en lassociant un port. Une fois la connexion
(bidirectionnelle) tablie via des sockets entre un processus client et un
processus serveur, ceux-ci peuvent communiquer en utilisant les mmes
primitives (read, write) que pour laccs aux fichiers.
O. Dalle (cours original de S. Krakowiak)

7-4

Place des sockets


Les sockets fournissent une
interface daccs, partir dun
hte, aux interfaces de transport
TCP et UDP
systme
TCP (mode connect) : une
liaison est tablie au pralable
entre deux htes, et ensuite les
messages (plus exactement des
flots doctets) sont changs sur
cette liaison
UDP (mode non connect) :
aucune liaison nest tablie. Les
messages sont changs
rseau
individuellement

Application

sockets mode
connect

sockets mode
non connect

TCP

UDP

interfaces
socket
interfaces
transport
interface
rseau

IP

Nous ne considrons que des sockets en mode connect


O. Dalle (cours original de S. Krakowiak)

7-5

Le protocole TCP
Principales caractristiques de TCP
Communication bidirectionnelle par flots doctets
Transmission fiable
Fiabilit garantie ds lors que la liaison physique existe
Transmission ordonne
Ordre de rception identique lordre dmission
Contrle de flux
Permet au rcepteur de limiter le dbit dmission en fonction de ses
capacits de rception
Contrle de congestion
Permet dagir sur le dbit dmission pour viter la surcharge du rseau
ne pas confondre contrle de flux (entre rcepteur et metteur ) et contrle de
congestion (entre rseau et metteur)
O. Dalle (cours original de S. Krakowiak)

7-6

Sockets ct serveur (1)


Un serveur fournit un service des clients. Il doit donc attendre une
demande, puis la traiter.
Les fonctions dattente et de traitement sont spares, pour permettre au
serveur dattendre de nouvelles demandes pendant quil traite des requtes
en cours.
socket serveur

connsock

attente

serveur

La socket serveur est


associe un port connu
(par ex. port 80 pour un
serveur web, etc.)

socket serveur

demande de
connexion

connsock

cration
socket de
communication
O. Dalle (cours original de S. Krakowiak)

serveur
newsock

La socket de communication
est associe au mme
numro de port que la socket
serveur, mais avec un
descripteur diffrent
7-7

Sockets ct serveur (2)


On procde en 4 tapes, dcrites schmatiquement ci-aprs (dtails plus tard)
socket serveur

tape 1 : crer une socket :


connsock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM, 0)

serveur

Internet

TCP

protocole,
sans usage ici

connsock est un objet socket


socket serveur

port
serveur

tape 2 : associer la socket un port:


Crer un adresse locale (couple {adresse,port})
serveraddr = ("",5678)
connsock.bind(serveraddr)

O. Dalle (cours original de S. Krakowiak)

7-8

Sockets ct serveur (3)


socket serveur
file

tape 3 : indiquer que cest une socket serveur


QUEUE_SIZE = 5
# par exemple
connsock.listen(QUEUE_SIZE)

serveur
Taille max de la file dattente des demandes

Une socket serveur est en attente de demandes de connexion. Si une


demande arrive pendant quune autre est en cours de traitement, elle est
place dans une file dattente. Si une demande arrive alors que la file est
pleine, elle est rejete (pourra tre refaite plus tard) ; voir primitive connect
plus loin.

O. Dalle (cours original de S. Krakowiak)

7-9

Sockets ct serveur (4)


socket serveur
file

tape 4a : se mettre en attente des demandes


newsock,(addr,port) = connsock.accept()

serveur

la primitive accept est bloquante

prte accepter les demandes de connexion


socket serveur
demande

servfd
file

tape 4b : aprs acceptation dune demande


newsock,(addr,port) = connsock.accept()

cration

serveur
newsock
socket de
communication

nouvel objet socket


Il sera utilis pour envoyer ou
recevoir des donnes sur la
nouvelle connexion

O. Dalle (cours original de S. Krakowiak)

adresse et port du client qui


a initi la nouvelle
connexion.
7-10

Rsum des primitives pour les sockets ct serveur


import socket
sock = socket.socket(domain, type, protocol)
# cre une socket client ou serveur, renvoie descripteur)
sock.bind((addr,port))
# associe une socket une adresse locale
sock.listen(maxqueuesize)
# dclare une socket comme serveur avec taille max queue
readsock = sock.accept()
# met une socket serveur en attente de demandes de connexion

Il existe en outre une primitive select, traite plus loin.

O. Dalle (cours original de S. Krakowiak)

7-11

Sockets ct client (1)


On procde en 2 tapes, dcrites schmatiquement ci-aprs
On suppose que lon connat ladresse dun serveur et le numro de port dune
socket serveur sur celui-ci (un processus serveur est en attente sur ce port)
tape 1 : crer une socket :

N.B. : opration
identique la cration
dune socket serveur

clisock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM, 0)

Internet

TCP

protocole,
sans usage ici

socket serveur
clientfd

socket client

client

port

serveur
Le serveur est en attente
sur la socket (accept)

O. Dalle (cours original de S. Krakowiak)

7-12

Sockets ct client (2)


tape 2 : tablir une connexion entre la socket client et le serveur
addr = ("www.unice.fr",80)
# remplir serveraddr avec adresse et n port du serveur
clisock.connect(addr)
# renvoie 0 si succs, 1 si chec

connect envoie une demande de connexion vers la socket serveur


le numro de port associ la socket
client est allou par le systme

clientfd

connect

socket serveur

socket client

port
cration

client

serveur

connexion tablie

connfd
Le client et le serveur peuvent maintenant dialoguer sur la connexion
O. Dalle (cours original de S. Krakowiak)

7-13

Rsum des primitives pour les sockets ct client


import socket
clisock = socket.socket(domain, type, protocol);
# cre une socket client ou serveur, renvoie descripteur)
clisock.connect((addr,port))
# envoie une demande de connexion un serveur sur un
# port donn

O. Dalle (cours original de S. Krakowiak)

7-14

changes sur une connexion entre sockets


Une fois la connexion tablie, le client et le serveur disposent chacun dun
object socket vers lextrmit correspondante de la connexion.
Cet objet fonctionne de faon un peu similaire un descripteur de fichier :
on peut lutiliser pour les mthodes recv et send ; on le ferme avec close.

Client

clientfd

O. Dalle (cours original de S. Krakowiak)

connexion
(bidirectionnelle)

servfd
connfd

Serveur

7-15

Un application client-serveur avec sockets (1)


Principes de la programmation dune application avec sockets (les dclarations
sont omises).
Ct serveur :
listensock = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
listensock.bind(("",port))
listensock.listen(5)
# cre une socket serveur associe au numro de port "port"
while True:
connfd,(fromaddr,fromport) = listensock.accept()
# accepte la connexion dun client
# on peut communiquer avec ce client sur connfd
server_body(connfd) # le serveur proprement dit...
# lit les requtes et renvoie les rponses sur connfd
# lorsque ce serveur se termine, on ferme la connexion
connfd.close()
# maintenant on va accepter la prochaine connexion
O. Dalle (cours original de S. Krakowiak)

7-16

Un application client-serveur avec sockets (2)


Principes de la programmation dune application avec sockets (les dclarations
sont omises).
Ct client :
clisock = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
clisock.connect(("www.unice.fr",port))
# ouvre une connexion vers le serveur
client_prog(clisock)
# envoyer requtes et recevoir rponses avec clientfd
# en utilisant recv et send
# la fin des changes, fermer le descripteur
clisock.close()

O. Dalle (cours original de S. Krakowiak)

7-17

Un application client-serveur avec sockets (3)

Pour excuter lapplication :


Lancer le programme serveur sur une machine, en indiquant un numro de
port (>1023, les numros 1023 sont rservs) ; de prfrence en travail de
fond
Lancer le programme client sur une autre machine (ou dans un autre
processus de la mme machine), en spcifiant adresse du serveur et
numro de port
N.B. On na pas prvu darrter le serveur (il faut tuer le processus qui lexcute).
Dans une application relle, il faut prvoir une commande pour arrter
proprement le serveur

O. Dalle (cours original de S. Krakowiak)

7-18

Client-serveur en mode itratif


Les programmes prcdents ralisent un serveur en mode itratif : un
seul client est servi la fois. Schma :
t=socket()
t.bind()
s=socket()

Client

t.listen()

Serveur

connexion initiale

s=t.accept()

s.connect()
s.send()

s.recv()

s.close()
exit()
O. Dalle (cours original de S. Krakowiak)

requte

rponse

boucle dinteraction clientserveur (spcifique de


lapplication)

s.recv()

attente
nouvelle
connexion

s.send()

s.close(s)

7-19

Client-serveur en mode concurrent (1)

Pour raliser un serveur en mode concurrent, une solution consiste


crer un nouveau processus pour servir chaque demande de connexion, le
programme principal du serveur ne faisant que la boucle dattente sur les
demandes de connexion.
Donc il y a un processus principal (appel veilleur) qui attend sur accept().
Lorsquil reoit une demande de connexion, il cre un processus fils (appel
excutant) qui va interagir avec le client. Le veilleur revient se mettre en
attente sur accept(). Plusieurs excutants peuvent exister simultanment.

O. Dalle (cours original de S. Krakowiak)

7-20

Client-serveur en mode concurrent (2)


Serveur
itratif

Serveur concurrent
Veilleur

t=socket()
t.bind()

t=socket()
bind()

t.listen()
Excutant

listen()
s=accept()
read()
traitement
write()
close(s)

t.close()

s=t.accept()

Client

fork()

s=socket()
s.close()

s.read()

s.connect()
s.send()

traitement

traitement

s.send()

s.recv()

s.close()
exit()

O. Dalle (cours original de S. Krakowiak)

boucle du veilleur
(attente de nouvelles
connexions)

Lexcutant (fils du veilleur) hrite


des descripteurs des sockets t et s.
Il ferme t (socket serveur) et garde s
(communication)

s.close()
exit()
7-21

La primitive select.select

Par dfaut l'appel read ou recv est bloquant


S'il n'y a rien a lire, on attend indfiniment...

Comment lire et recevoir de plusieurs sources en meme

temps ?
Par exemple attendre en mme temps:
soit une entre au clavier => lire fd=0
soit l'arrive d'un message sur un socket connect =>lire listensock
soit l'arrive d'une demande de connection => lire connsock
...
Pb: si je me bloque en attendant sur fd=0 (stdin=clavier), je ne peux pas
savoir ce qui se passe sur listensock ou connsock

Solutions
Serveur concurrent
select.select
O. Dalle (cours original de S. Krakowiak)

7-22

Exemple d'utilisation de select.select

liste_lectures = [clisock,sys.stdin]
# en entre on surveille clisock et sys.stdin
liste_ecritures,liste_erreurs = [],[]
# en criture et en erreur on ne surveille rien
readers,writers,errors =
select.select(liste_lectures,liste_ecritures,
liste_erreurs,delai)
# on recupre le rsultat de l'attente dans 3 listes
for input in readers:
if input == clisock:
# ici on a quelque chose a lire sur clisock
msg = clisock.recv(1000) # ne bloque pas !
if input == sys.stdin:
# ici on a quelque chose a lire sur stdin
msg = sys.stdin.readline() # ne bloque pas

O. Dalle (cours original de S. Krakowiak)

7-23

Rsum de la sance 7

Communication par sockets en mode connect


Principe
Primitives socket, bind, listen, accept, connect
Utilisation des primitives

Programmation client-serveur avec sockets


Serveur itratif
Serveur processus concurrents

Select

O. Dalle (cours original de S. Krakowiak)

7-24

S-ar putea să vă placă și