Windows Sockets : fonctionnement des sockets avec des archives
Cet article explique comment un objet CSocket , un objet CSocketFile et un objet CArchive sont combinés pour simplifier l’envoi et la réception de données via un socket Windows.
L’article Windows Sockets : Exemple de sockets à l’aide d’archives présente la PacketSerialize
fonction. L’objet archive dans l’exemple PacketSerialize
fonctionne beaucoup comme un objet archive passé à une fonction sérialiser MFC. La différence essentielle est que pour les sockets, l’archive est attachée à un objet CFile standard (généralement associé à un fichier de disque) mais à un CSocketFile
objet. Au lieu de se connecter à un fichier de disque, l’objet CSocketFile
se connecte à un CSocket
objet.
Un CArchive
objet gère une mémoire tampon. Lorsque la mémoire tampon d’une archive de stockage (envoi) est complète, un objet associé CFile
écrit le contenu de la mémoire tampon. Le vidage de la mémoire tampon d’une archive attachée à un socket équivaut à envoyer un message. Lorsque la mémoire tampon d’une archive de chargement (réception) est pleine, l’objet CFile
cesse de lire jusqu’à ce que la mémoire tampon soit à nouveau disponible.
La classe CSocketFile
dérive de CFile
, mais elle ne prend pas en charge les fonctions membres CFile telles que les fonctions de positionnement (Seek
, GetLength
, SetLength
etc.), les fonctions de verrouillage (LockRange
, UnlockRange
ou la GetPosition
fonction). Tout l’objet CSocketFile doit effectuer des opérations d’écriture ou de lecture de séquences d’octets vers ou à partir de l’objet associé CSocket
. Étant donné qu’un fichier n’est pas impliqué, des opérations telles que Seek
et GetPosition
n’ont aucun sens. CSocketFile
est dérivé de CFile
, de sorte qu’il hérite normalement de toutes ces fonctions membres. Pour éviter cela, les fonctions membres non prises en charge CFile
sont remplacées pour CSocketFile
lever une exception CNotSupportedException.
L’objet CSocketFile
appelle des fonctions membres de son CSocket
objet pour envoyer ou recevoir des données.
La figure suivante montre les relations entre ces objets des deux côtés de la communication.
CArchive, CSocketFile et CSocket
L’objectif de cette complexité apparente est de vous protéger de la nécessité de gérer les détails du socket vous-même. Vous créez le socket, le fichier et l’archive, puis commencez à envoyer ou à recevoir des données en l’insérant dans l’archive ou en l’extrayant de l’archive. CArchive, CSocketFile et CSocket gèrent les détails en arrière-plan.
Un CSocket
objet est en fait un objet à deux états : parfois asynchrone (l’état habituel) et parfois synchrone. Dans son état asynchrone, un socket peut recevoir des notifications asynchrones à partir de l’infrastructure. Toutefois, pendant une opération telle que la réception ou l’envoi de données, le socket devient synchrone. Cela signifie que le socket ne recevra aucune autre notification asynchrone tant que l’opération synchrone n’est pas terminée. Comme il bascule les modes, vous pouvez, par exemple, faire quelque chose comme suit :
void CMySocket::OnReceive(int nErrorCode)
{
if (0 == nErrorCode)
{
CSocketFile file(this);
CArchive ar(&file, CArchive::load);
CString str;
ar >> str;
}
}
S’il CSocket
n’a pas été implémenté en tant qu’objet à deux états, il peut être possible de recevoir des notifications supplémentaires pour le même type d’événement pendant le traitement d’une notification précédente. Par exemple, vous pouvez obtenir une OnReceive
notification lors du traitement d’un OnReceive
. Dans le fragment de code ci-dessus, l’extraction str
de l’archive peut entraîner une récursivité. En basculant des états, CSocket
empêche la récursivité en empêchant les notifications supplémentaires. La règle générale n’est pas une notification dans les notifications.
Remarque
Un CSocketFile
fichier peut également être utilisé en tant que fichier (limité) sans CArchive
objet. Par défaut, le paramètre bArchiveCompatible du constructeur a la CSocketFile
valeur TRUE. Cela spécifie que l’objet de fichier est utilisé avec une archive. Pour utiliser l’objet de fichier sans archive, passez FALSE dans le paramètre bArchiveCompatible.
Dans son mode « compatible archive », un CSocketFile
objet offre de meilleures performances et réduit le danger d’un « interblocage ». Un interblocage se produit lorsque les sockets d’envoi et de réception sont en attente les uns des autres, ou en attendant une ressource commune. Cette situation peut se produire si l’objet CArchive
a travaillé avec la CSocketFile
façon dont il le fait avec un CFile
objet. Avec CFile
, l’archive peut supposer que s’il reçoit moins d’octets qu’il n’a demandé, la fin du fichier a été atteinte. Toutefois, les CSocketFile
données sont basées sur des messages ; la mémoire tampon peut contenir plusieurs messages. Par conséquent, la réception d’un nombre inférieur au nombre d’octets demandés n’implique pas la fin du fichier. L’application ne bloque pas dans ce cas, car elle peut le faire CFile
, et elle peut continuer à lire des messages à partir de la mémoire tampon tant que la mémoire tampon n’est pas vide. La fonction IsBufferEmpty est CArchive
utile pour surveiller l’état de la mémoire tampon de l’archive dans ce cas.
Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives