J'ai un problème très gênant que j'ai trouvé plusieurs fois sur d'autres forums, mais je ne trouve pas de solution appropriée. Le problème est RECV () renvoie 0 sur les derniers octets d'une connexion. Voici quelques informations de base. P>
J'appelle Envoyer () plusieurs fois (petits morceaux) et du côté du client 53 octets sont transférés. Le serveur appelle RECV () plusieurs fois (requêtes de 4 octets) et lisez 49 octets, puis retourne 0 (54 octets - 49 octets, donc 4 octets sont manquants). P>
MSDN et certains forums écrivent pour des prises non bloquantes: P>
MSDN dit également: P>
Utilisation des fonctions de fermeture ou d'arrêt avec SD_SEND ou SD_BOTH Résultats dans un signal de libération étant envoyé sur le canal de contrôle. Dû à l'utilisation d'ATM de signal séparé et de canaux de données, il est possible que Un signal de libération pourrait atteindre l'extrémité distante avant le dernier de la Les données atteignent sa destination, entraînant une perte de ces données. Un Les solutions possibles programment un délai suffisant entre le dernier données envoyées et la fonction de fermeture ou d'arrêt appelle à un guichet automatique Prise. P> blockQuote>
Ceci est considéré dans l'exemple de RECV () et d'envoi (): http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121 (v = vs.85) .aspx p>
Mais toujours pas de succès, je reçois toujours des interruptions dans 10% de toutes les connexions après la réception des 49 octets, 90% des connexions réussissent. Des idées? Thx. P>
3 Réponses :
RECV () code> retourne 0 uniquement lorsque vous demandez un tampon de 0 octet ou que l'autre pair a gracieusement déconnecté. Si vous ne recevez pas toutes les données que vous attendez, vous ne lisez pas correctement les données pour commencer. Veuillez mettre à jour votre question avec votre code actuel. P>
Je suppose que vous n'envoyez pas vraiment toutes les données que vous pensez être envoyées. Découvrez: P>
Qu'est-ce que SO_LINGER a à voir avec ne pas envoyer toutes les données que vous pensez que vous envoyez?
Parce que c'est tout le problème SO_LINGER. Vous écrivez toutes vos données (vous pensez) et fermez votre prise. Ce que vous avez réellement fait a été mis les données sur le tampon d'envoi du système d'exploitation ... puis fermée la prise. L'autre côté voit des données partielles puis une étroite.
- RECV () Retourne définitivement = 0 lorsque l'autre côté a fermé la connexion li> ul>
Ceci n'est pas complètement vrai, dans le code suivant à l'aide de Winsock2 TCP sans blocage, lorsque aucune donnée n'est disponible, sélectionnez Retours 1 et RECV renvoie 0, de même que WsageTlasterRor (). P>
::shutdown(socket, SD_BOTH); ::closesocket(socket);
Si RECV () code> renvoie zéro, la peer a fermé la connexion. Le mode non bloqué n'a rien à voir avec cela.
Je soupçonne que vous faites partie de plusieurs erreurs de programmation de socket classiques. J'ai quelques idées, mais je préférerais voir votre code avant d'écrire quelque chose.
SO_LINGER avec un délai d'attente positif en mode non bloquant n'a pas de sens. Il ne bloquera ni le délai d'expiration.