PROFDINFO.COM

Votre enseignant d'informatique en ligne

Les sockets asynchrones

Principe de base

Les procédures Accept et Receive de Socket sont bloquantes, c'est-à-dire que lorsqu'on les appelle, l'exécution du thread en cours est suspendue jusqu'à ce qu'elles se terminent. Accept se termine lorsqu'un client demande une connexion et que le socket actif a été créé. Receive se termine lorsque l'autre partie a envoyé des données sur le socket et qu'on les a lues.

Ceci nous oblige à utiliser des threads pour pouvoir créer un serveur qui peut accepter et communiquer avec plusieurs clients à la fois.

Les sockets asynchrones utilisent le principe des événements afin de permettre des opérations non bloquantes. Accept et Receive seront donc remplacées par BeginAccept et EndAccept, puis BeginReceive et EndReceive. Les fonctions Begin ne sont pas bloquantes et utilisent un délégué de type AsyncCallback pour passer une fonction qui sera exécutée automatiquement dans un autre thread lorsque le moment sera approprié (lorsque l'événement voulu sera déclenché). La gestion des threads et des événements impliqués est prise en charge automatiquement par .NET.

Les fonctions End sont bloquantes et devront être implémentées dans les fonctions passées aux fonctions Begin. Elles doivent absolument accepter un paramètre de type IAsyncResult (à cause de la signature du délégué). Ce paramètre permet toutefois une communication entre la fonction Begin et la fonction End. On y placera normalement un Object quelconque (appelé state) contenant notre socket et notre tableau de bytes. À la fin d'une fonction appelée par Begin, on refera normalement un Begin de façon à ce que le tout ne se termine pas sur-le-champ et qu'un autre thread en attente soit créé.

Voyez les exemples de code ici: le serveur asynchrone et le client asynchrone. Notez que pour des raisons de simplicité, le client ne fait qu'émettre et le serveur que recevoir, mais évidemment, on pourrait (et devrait!) implémenter les deux fonctionnalités dans les deux programmes afin de permettre une communication full duplex. Ceci fait en sorte que le client est codé comme un client synchrone bien banal - toute la complexité est dans le serveur. Notez également que rien n'est prévu ici pour fermer les sockets utilisés de façon gracieuse, ni de réutiliser les sockets actifs après leur déconnexion.