• [^] # Re: TCP

    Posté par . En réponse au message client serveur par socket en clientThread. Évalué à 2. Dernière modification le 15 octobre 2016 à 00:08.

    -Est ce que tout les octects du fichiers seront à peu près en ordre ?

    TCP: pas à peu près mais complètement. Car chaque paquet est numéroté en séquence. Donc le receveur est en mesure de savoir ce qu'il lui manque, et il peut induire la retransmission de certains paquets qu'il n'aurait pas reçu. Ce qui est retourné par l'appel recv()/read() est garanti d'être dans l'ordre. Mais le receveur n'a aucun moyen de savoir si le receveur ne va pas encore envoyer des données. Si je te téléphone, ben je te dirais "au revoir" avant de raccrocher, tu sauras alors que je n'aurai plus rien à te dire. Par contre si je raccroche sans rien dire, tu ne saura pas si la communication a été coupée ou si j'ai effectivement raccroché. (note que TCP a théoriquement moyen de détecter la "fermeture" d'une connection, mais ça n'est pas très fiable car un firewall pourrait simuler la fermeture de la connexion, ton application n'y verrait que du feu).
    UDP: non

    -Est ce qu'on aura une moitié de fichier à destination ou rien du tout ?

    On aura ce qu'on aura reçu jusque là, modulo ce qui n'a pas encore pu être réassemblé (genre si on reçoit les paquets TCP 1 - 2 - 4 - 5, ben l'OS ne pourra au maximum ne retourner que 1 - 2 à l'application).

    -Tu parles du streaming mais ce n'est pas plutot UDP qui est utilisé pour ca ?

    Non, TCP == connecté (ou stateful) == on travaille avec un stream, une connection. Il est "découpé en paquet" de manière arbitraire par la stack tcp/ip et/ou les routeurs intermédiaires. On a la garantie que ce qui est read()/recv() le sera dans le même ordre que ce qui a été write()/send() de l'autre, mais on n'a pas de garantie quant à la taille des paquets tant en écriture qu'en lecture. La pile TCP a le droit de fusionner plusieur write en un seul paquet ou inversément de diviser un write en plusieurs paquets du côté émission. Similairement du côté réception, un paquet pourrait être réparti sur deux appels à read, ou encore plusieurs paquets pourraient être fusionnés. Cela permet d'augmenter les performance: par exemple en fusionnant des write() successifs de petite taille dans un seul paquet ou inversément d'attendre un certain temps après la réception d'un paquet pour voir s'il y en a un juste derrière dont les données pourraient être retournées lors du même appel à read()/recv().

    UDP == non-connecté (ou stateless) == l'unité de transfert est le datagramme. Dans ce cas, il me semble que la taille du buffer passé à recv/recvfrom doit être supérieure à la taille du plus gros datagramme recevable. En tout cas ce qui est certain c'est que l'os ne "réassemble" pas plusieurs datagrammes tel qu'il le ferait en TCP; car cela impliquerait l'utilisation d'un numéro de séquence attaché aux paquets afin d'éviter des le mélanger et rendrait de facto le protocole "stateful"... Cela veut dire qu'en pratique il faudra que le datagramme soit inférieur au plus petit MTU de la route utilisé (parce que sinon il va se retrouvé découpé en morceaux par le routeur et donc le récepteur n'aura plus aucun moyen de réassembler les fragments dans l'ordre, le paquet sera perdu).

    Comme Alumnium95 le mentionne, il y a des séparations entre les couches physiques, de protocoles (IP/TCP, IP/UDP) et applicatives (HTTP, DNS, etc.) Mon commentaire initial porte à confusion, je parlait de protocole dans la couche applicative évidemment. Pour éviter le cas de figure du routeur qui prend feu justement. Un protocole applicatif serait, p.e., d'écrire la chaine "ATTENTION J'ENVOIS UN FICHIER DE 42 OCTECTS" suivit du fichier en question, le récepteurs est donc au courant qu'il devra compter 42 octets à compter de la fin de cette chaîne reçue... En UDP, le protocole applicatif doit gérer la retransmission lui même (ou pas, si ça n'est pas utile). Un exemple de protocole serait "OCTET 24 VAUT 251" dans un sens, dans l'autre "JE N'AI PAS RECU L'OCTET 31, PRIERE DE LE REENVOYER". La confusion avec stream vient du fait qu'en générale, on n'utilise udp lorsque l'on n'a pas besoin de retransmission, par exemple lorsqu'on stream un flux audio en direct, ben si on a perdu une trame audio alors tant pis, ça n'aurait aucun sens de vouloir la diffuser plus tard (ça serait inaudible).