2010-06-10 12 views
1

Il s'agit plus d'une question de conception que d'une question de code spécifique, je suis sûr que je manque l'évidence, j'ai juste besoin d'un autre ensemble d'yeux.Winsock WSAAsyncSélectionner l'envoi sans un tampon infini

Je suis en train d'écrire un serveur multi-client basé sur WSAAsyncSelect, chaque connexion est transformé en un objet d'une classe de connexion je l'ai écrit qui contient les paramètres associés et des tampons etc.

Ma question concerne FD_WRITE, je comprends comment il fonctionne: Un FD_WRITE est envoyé immédiatement après l'établissement d'une connexion. Par la suite, vous devriez envoyer jusqu'à ce que WSAEWOULDBLOCK soit reçu à quel point vous stockez ce qui reste à envoyer dans un tampon, et attendez d'être informé que vous pouvez l'envoyer à nouveau.

C'est là que j'ai un problème, quelle est la taille de ce tampon de maintien dans chaque objet de connexion? La quantité de temps jusqu'à ce qu'un nouveau FD_WRITE soit reçu est inconnu, je pourrais essayer d'envoyer beaucoup de substance pendant cette période, en ajoutant tout le temps à mon tampon sortant. Si je rends la mémoire tampon dynamique, l'utilisation de la mémoire peut devenir incontrôlable si, pour une raison quelconque, je ne peux pas envoyer() et réduire le tampon. Donc, ma question est de savoir comment gérez-vous généralement cette situation? Remarque: Je ne parle pas de la mémoire tampon réseau utilisée par winsock, mais une de mes propres créations permet de "mettre en file d'attente" les envois.

J'espère avoir bien expliqué cela, merci à tous!

Répondre

0

Naturellement, la conception correcte dépend de la nature de votre application.

Certains programmes peuvent prédire la quantité de données pouvant être générées avant que quelque chose doive être fait avec, afin qu'ils puissent utiliser un tampon de taille fixe. Un protocole que j'ai conçu, par exemple, avait une structure de réponse-commande et un préfixe de longueur de 2 octets, de sorte que je pouvais utiliser des tampons 64K et savoir que je ne les déborderais jamais. Si un tampon est plein, le programme doit attendre une réponse avant d'être autorisé à envoyer des données à partir de ce tampon, donc plus de données ne seront ajoutées à ce tampon.

Une autre bonne utilisation pour les tampons de taille fixe est lorsque les données proviennent d'une autre source d'E/S. Envisager un serveur Web: à la base, il slurps fichiers à partir du disque et les recrache sur le fil. Vous savez donc combien vous lisez à partir du disque à la fois, de sorte que vous savez à quelle taille vos tampons doivent être.

J'ai du mal à trouver une bonne raison d'utiliser des tampons dynamiques.

La principale raison pour laquelle vous n'en avez pas besoin est TCP's sliding window. Si l'un des homologues de connexion cesse de recevoir des données, la pile de l'homologue distant arrêtera d'envoyer des données lorsque la fenêtre TCP se remplira. Les données non lues resteront dans les tampons de la pile de réception jusqu'à ce que le programme auquel elle a été envoyée le demande. Cela donne au récepteur un moyen d'étrangler les données entrantes à un niveau qu'il peut gérer. Autant que je sache, cela rend les tampons de taille fixe pratiques dans toutes les conditions.

+0

Salut merci pour votre réponse. Mon application est configurée de manière similaire, les paquets sont définis en taille-instruction-données, mesurant au maximum 64k chacun, donc pour la réception je peux facilement définir une taille de buffer maximum. Cela me laisse avec une autre question que je ne sais pas comment répondre. Cela concerne le scénario "buffer full", comment puis-je gérer cela. Si un utilisateur clique sur un bouton qui enverrait un paquet au serveur, mais cela ne peut pas être terminé parce que le tampon est plein, mon interface utilisateur n'agit pas comme prévu. Suis-je laissé attendre que l'utilisateur répète la commande? Merci! – Xexr

+0

Je voudrais construire chaque paquet sortant dès que vous savez comment le créer, le mettre dans une liste chaînée, et demander à votre gestionnaire FD_WRITE d'utiliser ces blocs pour envoyer. –

+0

Voir, mais une liste liée est juste la mémoire dynamique gérée - et pas si dissemblable de mon approche originale. Mais merci pour votre aide, je vais mettre à jour mon code pour utiliser des listes liées plutôt que la solution personnalisée que j'ai en ce moment. – Xexr