Question

J'ai remarqué un problème où l'événement. semble arrêter de tirer. Le même SAEA peut tirer correctement et être remplacé dans la piscine plusieurs fois, mais finalement toutes les instances cesseront de tirer, et parce que le code pour les remplacer dans la piscine est dans le gestionnaire d'événements, la piscine se vide.

La circonstances suivantes sont également apparemment vrais:

1) Cela ne semble se produire que lorsqu'un socket côté serveur envoie des données à l'un des clients connectés. Lorsque la même classe se connecte en tant que client, il ne semble pas dysonner.

2) Il semble se produire sous une charge élevée. Le nombre de threads semble se glisser jusqu'à ce que l'erreur se produise finalement.

3) Une plate-forme d'essai sous contrainte similaire ne semble jamais au dysfonctionnement. (Ce n'est que 20 messages par seconde, et la plate-forme d'essai a été prouvée à 20k)

Je ne vais pas pouvoir coller le code plutôt compliqué, mais voici un Description de mon code:

1) La principale inspiration est la suivante: http://vadmyst.blogspot.ch/2008/05/sample-code-for-tcp-server-using.html. Il montre comment connecter un port d'achèvement à l'aide d'un événement, comment obtenir différentes messages de taille sur la connexion TCP, etc.

2) J'ai un tampon d'octets dans lequel tous les Saas ont un morceau, qui ne se chevauche pas.

3) J'ai un pool d'objets de SAEAS, basé sur une carte de blocage. Cela jette si la piscine est vide trop longtemps.

4) En tant que serveur, je garde une collection de sockets renvoyés de la fonction Acceptasync, indexée par le point de terminaison du client. Un seul processus peut utiliser une instance comme serveur ainsi que plusieurs instances en tant que clients (formant un Web). Ils partagent le tampon de données et le pool de SAEAS.

Je me rends compte qu'il est difficile d'expliquer cela; Je le débogue depuis une journée et une nuit. En espérant juste que quelqu'un en a entendu parler ou a des questions ou des suggestions utiles.

Pour le moment, je soupçonne une sorte d'épuisement des filetages, ce qui a conduit le SAEAS à ne pas pouvoir appeler l'achèvement. Alternativement, une sorte de problème de tampon sur le tampon sortant.

Était-ce utile?

La solution

Donc, un autre jour de débogage et enfin j'ai une explication.

1) Les SAEAS ne tiraient pas l'événement terminé car ils n'ont pas pu en envoyer plus. Ceci est révélé par Wireshark dû à la vidange de la fenêtre TCP. (TCP Zerowindow)

2) La fenêtre TCP se vidait parce que la couche de mise en réseau passait un événement dans la pile qui a mis trop de temps à terminer, c'est-à-dire qu'il n'y a pas de producteur / consommateur entre la couche réseau et l'interface utilisateur. Ainsi, le réseau OP devrait attendre le dessin de l'écran avant d'envoyer l'ACK.

3) L'événement qui a pris trop de temps était un tirage au sort dans un gestionnaire d'événements sur l'interface graphique. La plate-forme d'essai était une fenêtre de console (qui résumait les messages entrants), c'est pourquoi il n'a pas causé de problème à une charge beaucoup plus élevée. Il est normal de ne pas redessiner l'écran sur chaque message, mais cela se produisait parce que le projet n'est pas encore terminé. Le taux de réadaptation aurait été fixé plus tard.

4) La solution à court terme consiste simplement à s'assurer qu'il n'y a pas de GUIS qui maintient le spectacle. Une solution plus robuste pourrait être de créer un producteur / consommateur sur la couche réseau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top