Partager via


La classe CSocket

Dérive de , hérite de CAsyncSocketson encapsulation de l’API Windows Sockets et représente un niveau d’abstraction supérieur à celui d’un CAsyncSocket objet.

Syntaxe

class CSocket : public CAsyncSocket

Membres

Constructeurs publics

Nom Description
CSocket::CSocket Construit un objet CSocket.

Méthodes publiques

Nom Description
CSocket::Attach Attache un SOCKET handle à un CSocket objet.
CSocket::CancelBlockingCall Annule un appel bloquant en cours.
CSocket::Create Crée un socket.
CSocket::FromHandle Retourne un pointeur vers un CSocket objet, en fonction d’un SOCKET handle.
CSocket::IsBlocking Détermine si un appel bloquant est en cours.

Méthodes protégées

Nom Description
CSocket::OnMessagePending Appelé pour traiter les messages en attente en attendant la fin d’un appel bloquant.

Notes

CSocket fonctionne avec des classes CSocketFile et CArchive pour gérer l’envoi et la réception de données.

Un CSocket objet fournit également un blocage, qui est essentiel à l’opération synchrone de CArchive. Les fonctions bloquantes, telles que Receive, , SendReceiveFrom, SendToet Accept (toutes héritées de ), CAsyncSocketne retournent pas d’erreur WSAEWOULDBLOCK dans CSocket. Au lieu de cela, ces fonctions attendent que l’opération se termine. En outre, l’appel d’origine se termine par l’erreur WSAEINTR si CancelBlockingCall elle est appelée alors qu’une de ces fonctions bloque.

Pour utiliser un CSocket objet, appelez le constructeur, puis appelez-le Create pour créer le handle sous-jacent SOCKET (type SOCKET). Les paramètres par défaut de Create la création d’un socket de flux, mais si vous n’utilisez pas le socket avec un CArchive objet, vous pouvez spécifier un paramètre pour créer un socket de datagramme à la place, ou lier à un port spécifique pour créer un socket de serveur. Connecter à un socket client à l’aide Connect du côté client et Accept côté serveur. Créez ensuite un CSocketFile objet et associez-le à l’objet CSocket dans le CSocketFile constructeur. Ensuite, créez un CArchive objet pour l’envoi et l’autre pour recevoir des données (si nécessaire), puis associez-les à l’objet CSocketFile dans le CArchive constructeur. Lorsque les communications sont terminées, détruisez les objets et CSocket les CArchiveCSocketFileobjets. Le SOCKET type de données est décrit dans l’article Windows Sockets : Arrière-plan.

Lorsque vous utilisez CArchiveCSocketFile et CSocketque vous pouvez rencontrer une situation où CSocket::Receive entre une boucle (par PumpMessages(FD_READ)) en attente de la quantité d’octets demandée. Cela est dû au fait que les sockets Windows n’autorisent qu’un seul appel recv par FD_READ notification, mais CSocketFile autorisent CSocket plusieurs appels recv par FD_READ. Si vous obtenez un FD_READ moment où il n’y a pas de données à lire, l’application se bloque. Si vous n’obtenez jamais d’autre FD_READ, l’application cesse de communiquer sur le socket.

Vous pouvez résoudre ce problème comme suit. Dans la OnReceive méthode de votre classe de socket, appelez CAsyncSocket::IOCtl(FIONREAD, ...) avant d’appeler la Serialize méthode de votre classe de message lorsque les données attendues à lire à partir du socket dépassent la taille d’un paquet TCP (unité de transmission maximale du support réseau, généralement au moins 1 096 octets). Si la taille des données disponibles est inférieure à nécessaire, attendez que toutes les données soient reçues, puis démarrez l’opération de lecture uniquement.

Dans l’exemple suivant, m_dwExpected correspond au nombre approximatif d’octets que l’utilisateur s’attend à recevoir. Il est supposé que vous le déclarez ailleurs dans votre code.

void CChatSocket::OnReceive(int nErrorCode)
{
   CSocket::OnReceive(nErrorCode);

   DWORD dwReceived;

   if (IOCtl(FIONREAD, &dwReceived))
   {
      if (dwReceived >= m_dwExpected) // Process only if you have enough data
         m_pDoc->ProcessPendingRead();
   }
   else
   {
      // Error handling here
   }
}

Remarque

Lorsque vous utilisez des sockets MFC dans des threads secondaires dans une application MFC liée statiquement, vous devez appeler AfxSocketInit chaque thread qui utilise des sockets pour initialiser les bibliothèques de sockets. Par défaut, AfxSocketInit il est appelé uniquement dans le thread principal.

Pour plus d’informations, consultez Windows Sockets dans MFC, Windows Sockets : Utilisation de Sockets avec archives, Windows Sockets : Fonctionnement des sockets avec archives, Sockets Windows : Séquence d’opérations, Sockets Windows : Exemples de sockets à l’aide d’archives.

Hiérarchie d'héritage

CObject

CAsyncSocket

CSocket

Spécifications

En-têteafxsock.h:

CSocket::Attach

Appelez cette fonction membre pour attacher le hSocket handle à un CSocket objet.

BOOL Attach(SOCKET hSocket);

Paramètres

hSocket
Contient un handle vers un socket.

Valeur de retour

Valeur différente de zéro si la fonction aboutit.

Notes

Le SOCKET handle est stocké dans le membre de données de l’objet m_hSocket .

Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives.

Exemple

class CSockThread : public CWinThread
{
public:
   SOCKET m_hConnected;

protected:
   CChatSocket m_sConnected;

   // remainder of class declaration omitted.

 

BOOL CSockThread::InitInstance()
{
   // Attach the socket object to the socket handle
   // in the context of this thread.
   m_sConnected.Attach(m_hConnected);
   m_hConnected = NULL;

   return TRUE;
}

 

// This listening socket has been constructed
// in the primary thread.
void CListeningSocket::OnAccept(int nErrorCode)
{
   UNREFERENCED_PARAMETER(nErrorCode);

   // This CSocket object is used just temporarily
   // to accept the incoming connection.
   CSocket sConnected;
   Accept(sConnected);

   // Start the other thread.
   CSockThread *pSockThread = (CSockThread*)AfxBeginThread(
       RUNTIME_CLASS(CSockThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
   if (NULL != pSockThread)
   {
      // Detach the newly accepted socket and save
      // the SOCKET handle in our new thread object.
      // After detaching it, it should no longer be
      // used in the context of this thread.
      pSockThread->m_hConnected = sConnected.Detach();
      pSockThread->ResumeThread();
   }
}

CSocket::CancelBlockingCall

Appelez cette fonction membre pour annuler un appel bloquant en cours.

void CancelBlockingCall();

Notes

Cette fonction annule toute opération de blocage en attente pour ce socket. L’appel de blocage d’origine se termine dès que possible avec l’erreur WSAEINTR.

Dans le cas d’une opération de blocage Connect , l’implémentation de Windows Sockets met fin à l’appel de blocage dès que possible, mais il peut ne pas être possible que les ressources de socket soient libérées tant que la connexion n’a pas été terminée (puis réinitialisée) ou expirée. Cela est susceptible d’être visible uniquement si l’application tente immédiatement d’ouvrir un nouveau socket (si aucun socket n’est disponible) ou de se connecter au même homologue.

Annulation d’une opération autre que Accept celle pouvant laisser le socket dans un état indéterminé. Si une application annule une opération de blocage sur un socket, la seule opération que l’application peut dépendre de la possibilité d’effectuer sur le socket est un appel à Close, bien que d’autres opérations puissent fonctionner sur certaines implémentations de Sockets Windows. Si vous souhaitez une portabilité maximale pour votre application, vous devez être prudent de ne pas dépendre des opérations après une annulation.

Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives.

CSocket::Create

Appelez la Create fonction membre après avoir construit un objet de socket pour créer le socket Windows et l’attacher.

BOOL Create(
    UINT nSocketPort = 0,
    int nSocketType = SOCK_STREAM,
    LPCTSTR lpszSocketAddress = NULL);

Paramètres

nSocketPort
Port particulier à utiliser avec le socket, ou 0 si vous souhaitez que MFC sélectionne un port.

nSocketType
SOCK_STREAM ou SOCK_DGRAM.

lpszSocketAddress
Pointeur vers une chaîne contenant l’adresse réseau du socket connecté, un nombre en pointillé tel que « 128.56.22.8 ». Le passage de la chaîne NULL pour ce paramètre indique que l’instance doit écouter l’activité CSocket du client sur toutes les interfaces réseau.

Valeur de retour

Différent de zéro si la fonction réussit ; sinon, 0 et un code d’erreur spécifique peut être récupéré en appelant GetLastError.

Notes

Create appelle Bind ensuite pour lier le socket à l’adresse spécifiée. Les types de sockets suivants sont pris en charge :

  • SOCK_STREAM Fournit des flux d’octets séquencés, fiables, bidirectionnel et bidirectionnel. Utilise le protocole TCP (Transmission Control Protocol) pour la famille d’adresses Internet.

  • SOCK_DGRAM Prend en charge les datagrammes, qui sont des mémoires tampons non fiables d’une longueur maximale fixe (généralement petite). Utilise le protocole UDP (User Datagram Protocol) pour la famille d’adresses Internet. Pour utiliser cette option, vous ne devez pas utiliser le socket avec un CArchive objet.

    Remarque

    La Accept fonction membre prend une référence à un nouvel objet vide CSocket comme paramètre. Vous devez construire cet objet avant d’appeler Accept. N’oubliez pas que si cet objet socket sort de l’étendue, la connexion se ferme. N’appelez Create pas ce nouvel objet socket.

Pour plus d’informations sur les sockets de flux et de datagramme, consultez les articles Windows Sockets : Arrière-plan, Sockets Windows : Ports et adresses de sockets et Sockets Windows : Utilisation de sockets avec archives.

CSocket::CSocket

Construit un objet CSocket.

CSocket();

Notes

Après la construction, vous devez appeler la Create fonction membre.

Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives.

CSocket::FromHandle

Retourne un pointeur vers un CSocket objet.

static CSocket* PASCAL FromHandle(SOCKET hSocket);

Paramètres

hSocket
Contient un handle vers un socket.

Valeur de retour

Pointeur vers un CSocket objet, ou NULL s’il n’y a pas CSocket d’objet attaché à hSocket.

Notes

Lorsqu’un SOCKET handle est donné, si un CSocket objet n’est pas attaché au handle, la fonction membre retourne NULL et ne crée pas d’objet temporaire.

Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives.

CSocket::IsBlocking

Appelez cette fonction membre pour déterminer si un appel bloquant est en cours.

BOOL IsBlocking();

Valeur de retour

Différent de zéro si le socket bloque ; sinon 0.

Notes

Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives.

CSocket::OnMessagePending

Remplacez cette fonction membre pour rechercher des messages particuliers de Windows et y répondre dans votre socket.

virtual BOOL OnMessagePending();

Valeur de retour

Différent de zéro si le message a été géré ; sinon 0.

Notes

Il s’agit d’un élément substituable avancé.

Les appels OnMessagePending de framework pendant que le socket pompe les messages Windows pour vous donner la possibilité de traiter les messages qui vous intéressent. Pour obtenir des exemples d’utilisation OnMessagePending, consultez l’article Windows Sockets : dérivation de classes de sockets.

Pour plus d’informations, consultez Windows Sockets : Utilisation de sockets avec archives.

Voir aussi

CAsyncSocket Classe
Graphique hiérarchique
CAsyncSocket Classe
CSocketFile Classe