2016-05-11 1 views
0

S'il vous plaît, quelqu'un m'aidera gentiment comment intercepter l'erreur d'opération de socket de la classe CAsyncSocket.En utilisant CAsynSocket, comment capturer le code de sortie des opérations de socket?

Si je fais ceci:

int iLen = recv(socket, socketBuffer, sizeBuffer, 0); 
if(iLen==SOCKET_ERROR) { 
    //handle error here 
} else { 
    //do something with the received data 
} 

Il renvoie toujours l'erreur, ce qui est WSAEWOULDBLOCK, et la même chose pour une autre opération comme send(), connect(), etc ...
Selon MSDN Ce n'est pas une erreur fatale, et il faut du temps pour que les actions soient terminées. Donc comment puis-je vérifier chaque fois que mon programme a recv() ou send() correctement?

+0

Le dernier argument de [ 'recv'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121 (v = vs.85) .aspx) est une valeur d'indicateur * integer *, pas un pointeur. Donc, vous ne devriez pas utiliser 'NULL' ici. –

+0

En ce qui concerne votre problème, 'WSAEWOULDBLOCK' vous indique simplement qu'il n'y a rien à recevoir pour le socket * non-bloquant *. Vous pouvez utiliser ['select'] (https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms740141 (v = vs.85) .aspx) ou [' WSAPoll'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms741669(v=vs.85).aspx) pour interroger si le socket (s) a quelque chose à lire. –

+0

Merci pour votre commentaire, dans MFC, ils définissent NULL comme 0; cependant, j'ai édité mon code comme suggestion. Pour le select(), je n'ai toujours aucune idée de comment l'utiliser. –

Répondre

1

tout d'abord vous ne devriez pas mélanger CAsyncSocket API et API Berkley Socket.

Votre gestionnaire OnReceive devrait ressembler à ceci:

CByteArray InBuffer; 
    InBuffer.SetSize(DEFAULT_RX_BUFFER_SIZE);  
    int nBytes = Receive(InBuffer.GetData(), (int)InBuffer.GetSize()); 

    switch (nBytes) 
    { 
     case 0: 
      ShutDown(CAsyncSocket::both); 
      break; 
     case SOCKET_ERROR: 
      if (::GetLastError() != WSAEWOULDBLOCK) 
       ShutDown(CAsyncSocket::both); 
      else 
       AsyncSelect(); 
      break; 
     default: 
      { 
       // TODO: data processing goes here 
      } 
      break; 
    } 
+0

Merci pour votre commentaire. Donc, je devrais faire la même chose pour Send(), Listen(), et Connect()? Btw, où DEFAULT_RX_BUFFER_SIZE est défini? Je ne peux pas le trouver. –

+0

Oui, il existe des gestionnaires OnConnect, OnSend et d'autres. La gestion des erreurs est à peu près la même. La constante 'DEFAULT_RX_BUFFER_SIZE' est définie par l'utilisateur. –

+0

Je sais que ce n'est pas dans la question, mais c'est complètement différent de ce à quoi je m'attends. Comment puis-je seulement obtenir les 4 premiers octets de l'ensemble? Parce que, j'ai effectivement emballé 2 données quand j'ai envoyé. Le premier est int, et le second est char *. Quand j'ai appliqué votre code, il tire tout dans le 'default:' –