Dialogue via les sockets créées
En langage C :
Une fois la connexion établie entre le client et le serveur, on dispose d'un canal de communication bidirectionnel identifiable par les adresses IP et port TCP de chacune de ses extrémités. De chaque côté, on pourra écrire ou lire dans sa socket via les fonctions write et read de la bibliothèque unistd.h (comme on le ferait pour un simple fichier).
Ecriture
La fonction write prend 3 paramètres :
- fd : Le premier paramètre est l'entier identifiant la socket.
- buf : Le second paramètre est l'adresse en mémoire d'un buffer contenant le message à envoyer dans le canal de communication.
- count : Le troisième paramètre est un entier indiquant le nombre de caractères à envoyer depuis le buffer vers le canal de communication.
La fonction retourne un entier :
- s'il est strictement positif, il correspond au nombre de caractères écrits dans le canal. Dans certain cas, il peut être inférieur à la valeur fournie par le troisième paramètre.
- S'il vaut 0, il indique qu'il n'y a plus rien à lire car on a fermé l'autre extrémité du canal de communication.
- S'il est strictement négatif, cela correspond à un code d'erreur dont certaines constantes sont les suivantes :
- EBADF : indique une erreur sur le premier paramètre qui n'est pas un descripteur de fichier valide.
- EFAULT : indique une erreur sur le second paramètre car l'adresse en mémoire qui a été fournie est hors de l'espace du processus.
- EINTR : l'arrivée d'un signal a interrompu l'écriture avant que des données soient écrites.
Lecture
La fonction read est une fonction bloquante (c'est à dire qu'elle attend jusqu'à ce qu'il y ait quelque chose à lire) qui prend 3 paramètres :
- fd : Le premier paramètre est l'entier identifiant la socket.
- buf : Le second paramètre est l'adresse en mémoire d'un buffer qui recevra le message lu depuis le socket.
- count : Le troisième paramètre est un entier (strictement positif) indiquant le nombre maximum de caractères que l'on peut placer dans le buffer passé en second paramètre.
La fonction retourne un entier :
- s'il est strictement positif, il correspond au nombre de caractères lus et placés dans le buffer.
- S'il vaut 0, il indique qu'il n'y a plus rien à lire car on a fermé l'autre extrémité du canal de communication.
- S'il est strictement négatif, cela correspond à un code d'erreur dont certaines constantes sont les suivantes :
- EBADF : indique une erreur sur le premier paramètre qui n'est pas un descripteur de fichier valide.
- EFAULT : indique une erreur sur le second paramètre car l'adresse en mémoire qui a été fournie est hors de l'espace du processus.
- EINTR : l'arrivée d'un signal a interrompu la lecture avant que des données soient lues.
Fermeture
La fonction shutdown prend 2 paramètres :
- fd : Le premier paramètre est l'entier identifiant la socket.
La fonction close prend 1 paramètre :
- fd : Ce paramètre est l'entier identifiant la socket.
Exemple :
void communication_client(int fd) {
char buf[256];
while ((len=read(fd,&buf,sizeof(buf)-1)) != 0) {
if (len > 0) {
buf[len]=0x00;
printf("%s\n",buf);
} else if (len != EINTR) {
printf("Erreur lecture socket !\n");
exit(1);
}
}
close(fd);
}
void communication_serveur(int fd) {
char msg[] = "Bonjour client.\nJe suis le serveur !\n";
int i, j, l, m=5;
l=strlen(msg);
for (i = 0; i < l ; i+=j ){
j=l-i;
j=write(fd, &msg[i], (j<m)?j:m);
if (j < 0 && j != EINTR) {
printf("Erreur écriture socket !\n");
exit(1);
}
}
}
PHP et Python :
Dans les langages comme PHP ou Python, il existe des bibliothèques faisant l'interface avec les fonctions systèmes.
PHP
Le code de l'exemple écrit en C devient en PHP :
function communication_client($socket) {
$m=5;
while (true) {
$buf = socket_read($socket,$m);
if ($buf == '') break;
if ($buf == false) {
echo "Erreur lecture socket !\n";
exit(1);
}
echo $buf;
}
}
function communication_serveur($socket) {
$msg="Bonjour client.\nJe suis le serveur !\n";
socket_write($socket,$msg);
}
Python
Le code de l'exemple écrit en C devient en Python :
def communication_client(sock) :
try :
m=5
while (True) :
buf=sock.recv(m)
if (buf =='') :
break
print(buf,end='')
except socket.error :
print("Erreur sur l'acceptation de connexion entrante !")
exit()
def communication_serveur(sock) :
msg="Bonjour client.\nJe suis le serveur !\n"
sock.send(msg)