2017-06-07 3 views
0

Compte tenu:Lorsque vous utilisez asio + ssl, la async_write ne transmet pas les données

asio::ssl::stream<asio::ip::tcp::socket&> &m_socket; 
async_write(self->m_socket, asio::buffer(self->m_v), 
    [self, handler](asio::error_code ec, std::size_t s) 
{ 
    handler(ec); 
}); 

Résultat: le gestionnaire est appelé avant que les données sont envoyées (fonction socket.send() est appelée). Résultat 2: les données sont effectivement envoyées après un long moment - dans mon cas reproductible environ 1 min. Par conséquent, la séquence d'événements est la suivante: 1. async_write est appelée; 2. le gestionnaire est appelé; 3. les données sont envoyées. Je crois que la séquence correcte doit être: 1. async_write est appelée; 2. les données sont envoyées. 3. le gestionnaire est appelé;

Cela n'arrive pas toujours, mais très reproductible. J'ai cherché partout sur Internet pour des cas similaires - rien trouvé.

J'ai besoin de conseils: que faire à ce sujet. Est-ce un bug dans asio ou est-ce un bug difficile dans mon programme et où chercher pour le réparer.

Je peux reproduire le cas facilement, peut fournir des fichiers journaux etc.

+0

Comment pouvez-vous dire que la commande est '1. 2. 3. »et non« 1. 3. 2. »? Voulez-vous dire que vous mesurez "3. les données sont reçues" au lieu de "3. les données sont envoyées"? – sehe

+0

1. J'ai mis des horodatages dans mes messages de journal. J'imprime un message de journal juste avant l'async_write et au début de son gestionnaire. Je détermine que 1 est avant 2 en fonction de ces horodatages. Comme pour 3, j'ai utilisé Microsoft Message Analyzer pour capturer le trafic réseau. La capture de Message Analyzer contient également des horodatages. Je crois que ces horodatages marquent le moment où le message entre dans le système de mise en réseau du code asio. Par conséquent, je suis sûr que la commande est 1. 2. 3. 2. Lorsque j'ai écrit le "3. les données sont envoyées" je voulais dire que les données ont été envoyées. – IakovK

+0

Si vous voyez un horodatage plus tard que 2. dans MMA, cela ne signifie pas qu'il a été envoyé après 2. (en fonction de l'endroit où le protocole affiche l'horodatage). Cela peut simplement signifier que MMA l'a vu plus tard. En outre, des choses comme l'algorithme de Nagle pourraient être en jeu. – sehe

Répondre

0

Si vous voyez un horodatage plus tard 2. MMA, qui ne veut pas dire qu'il a obtenu envoyé après 2. (selon l'endroit où la protocole que vous voyez l'horodatage). Cela peut simplement signifier que MMA l'a vu plus tard. En outre, des choses comme l'algorithme de Nagle pourraient être en jeu.

Essayez de définir TCP NODELAY, par ex.

socket.open(tcp::v4()); 
socket.set_option(tcp::no_delay(true)); 
socket.async_connect(endpoint, handler); 
+0

Je crois que MMA voit le message lorsqu'il entre dans le sous-système de mise en réseau Windows, c'est-à-dire lorsque la fonction socket.send est appelée. Pourriez-vous s'il vous plaît expliquer pourquoi je devrais croire autrement? – IakovK

+0

Parce que le MMA ne s'exécute pas dans le noyau et tous les processus sont planifiés correctement. Lequel obtient la prochaine tranche de temps sur laquelle le noyau n'est pas prévisible ou fixe – sehe

+0

Dans mon contexte, il est négligeable. Si la planification est équitable, chaque processus a une chance de s'exécuter en quelques millisecondes. Dans mon cas, le délai est de 50 secondes environ. Les millisecondes sont négligeables. – IakovK