Pour la première fois, j'essaie d'implémenter un protocole réseau sur TCP/IP. J'en ai conçu un mais je ne suis pas sûr que ce soit efficace.Quelles sont les meilleures pratiques de conception et d'implémentation de protocoles réseau?
Conception
Voici donc mon idée: après la connexion TCP/IP ouverture client avec le serveur, chaque fois qu'il veut faire une demande, d'abord, il envoie la taille de la demande suivie par un caractère de séparation (nouveau ligne ou espace) et après cette requête réelle (même principe est utilisé dans HTTP et je pense que dans la plupart des cas cette idée est utilisée). Par exemple, si le client veut envoyer GET ASD, il enverra en réalité 7 GET ASD (en supposant que l'espace est séparateur)
Pour le côté serveur, chaque serveur client dispose d'un tampon dans lequel il enregistre les demandes entrantes. Chaque fois qu'il obtient un nouveau morceau de caractères du client, le serveur l'ajoutera au tampon client correspondant. Après ce serveur va essayer d'obtenir la longueur du contenu de la requête (dans cet exemple 7) et vérifie si le reste de la longueur du tampon est plus ou égal à lui. Si c'est le cas, le serveur obtiendra le contenu réel de la requête, les traitera et les supprimera du tampon.
mise en œuvre
Tout cela était sur la conception du protocole, maintenant quelques notes sur la mise en œuvre réelle: Je pense que principal problème ici met en œuvre de manière efficace et la gestion des tampons.
Je pense qu'un tampon de taille 2 * MAX_SIZE_OF_ONE_REQUEST suffira pour servir un client car les blocs reçus par le serveur peuvent contenir simultanément la fin de la première requête et le début de la seconde. C'est mon hypothèse, si je me trompe et que nous avons besoin de plus ou moins d'espace, merci de me dire pourquoi.
Je pense qu'il ya deux façons de stocker les demandes dans le tampon jusqu'à ce qu'ils soient servis:
Chaque fois que le serveur reçoit une nouvelle partie des caractères, le serveur append sur le côté droit du tampon. Dès que le tampon contiendra une requête complète, le serveur la traitera et déplacera tout le reste du tampon vers la gauche au début de l'espace tampon.
Un tampon cyclique qui ne déplace pas le tampon au début après la demande de traitement.
C'est mes pensées sur la mise en œuvre des tampons avec async I/O à l'esprit (serveur utilisera epoll/kqueue/choisir de recevoir les demandes des clients). Je pense que si le serveur n'utilise pas d'E/S asynchrones pour la communication avec les clients, l'implémentation du tampon sera beaucoup plus simple.
Aussi je n'ai pas décidé comment le serveur devrait se comporter quand il reçoit une requête malformée. Devrait-il fermer la connexion avec le client?
Peut-être que j'ai beaucoup écrit mais je suis vraiment intéressé par ce sujet et je veux apprendre autant que possible. Je pense qu'il y en a beaucoup comme moi, donc tous les problèmes du monde réel sur ce sujet et les meilleures pratiques pour les résoudre seront très utiles.1.
Les exigences de l'API sont importantes à analyser avant de faire n'importe quel type de conception. Si vous pouvez élaborer sur ceux-ci, ce pourrait être plus facile. –
J'ai été très inspiré par Redis et pour l'apprentissage j'ai commencé le petit projet Kivi (K/V Store): http://github.com/giolekva/kivi Donc il y aura des commandes comme GET, SET, DEL, INCR, ... comme dans Redis. – giolekva
(Commentant parce que je n'ai pas une réponse complète à votre question): J'ai trouvé qu'il est préférable d'éviter la possibilité de demandes malformées. Dans ce cas, il est possible que la longueur et la requête soient incohérentes, donc je supprimerais la longueur. Au lieu de cela, vous pouvez avoir un terminateur spécial (''\ 0' 'fonctionne bien dans beaucoup de cas).Bien sûr, il y a toujours la possibilité que le client envoie une chaîne interminable pour surcharger le serveur, mais au moins vous ne serez pas en attente de plus d'octets si la longueur était erronée. – Jonathan