IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Web & réseau Delphi Discussion :

[Socket] Buffer et TCP [Archives]


Sujet :

Web & réseau Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    rgz
    rgz est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 14
    Par défaut [Socket] Buffer et TCP
    Bonjour à tous.
    J’aimerais parler un peu socket encore un fois.
    D’abord, je vous explique un peu la situation. Je réalise, pour être bref, une petite application capable d’envoyer des fichiers via un socket. Dans l’esprit, le serveur est celui qui permet d’envoyer les fichiers et le client permet de les recevoir. On ne parlera donc pas ici de « passive mode ».
    Le traitement des informations se fait donc exclusivement via des buffer envoyés entre les clients et les serveurs.

    Les structures de mon code sont en gros :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    const	taille_bloc =4000;
    	taille_direction_fichier =255;
     
     
    type T_Trame_client =Packed record
         fichier_req : string[taille_direction_fichier];
         bloc, nbr_trame : integer;            //4 bytes
    end;
    //Soit un total de 255+4*2 = 263 bytes
     
    type T_Trame_serveur =Packed record
         bloc, taille_envoye,nbr_bloc : integer;  //4 bytes
         nbr_trame_restant : integer; //4
         le_bloc : array[0..taille_bloc-1] of Byte;
    end;
    //Soit un total de 4000+4*4 = 4016 bytes
    La taille du bloc (assez énorme il est vrai) donnera la taille des données lues dans le fichier que l’on appellera « bloc ».
    La trame est donc l’ensemble des données envoyées protocole compris. Ici le protocole est donc pour le client :
    • -le fichier désiré (fichier_req)
      -le numéro du bloc désiré (bloc).
      -La variable nbr_trame permettra de demander au serveur plusieurs trames à la suite sans avoir à les équités à chaque arrivés.

    Du coté serveur, protocole est le suivant :
    • -Bloc est numéro du bloc du fichier envoyé,
      -Taille_envoye est la taille du bloc lu dans le fichier
      -Nbr_bloc est le nombre de bloc que contient le fichier
      -nbr_trame_restant est le nombre de trame que le serveur va envoyer sans attendre d’acquittement de la part du client. Ce nombre se décrémente jusqu’à 0 et à ce moment, le paquet composé de Trame_client.nbr_trame est terminé.

    Cette structure me permet donc de me connecter à un serveur quelconque et du lui demander un bout quelconque d’un fichier quelconque. On approche donc du principe du P2P. De plus, le client va être capable de gérer de lui même le nombre trames qui composeront le paquet serveur.

    Bon, maintenant je développe la partie OnServerRead et OnClientRead. Le coté server reçoit à chaque fois des petites trames et les traite facilement. Le coté client est déjà plus interressant puisque il contient à la fois un protocole à traiter mais aussi des données brutes à gérer (le_bloc). Il est donc important de vérifier la taille de la trame du serveur pour qu’elle puisse être intégrée à une variable de type T_Trame_Serveur. On en vient donc aux suprises…

    D’abord, je constate que le buffer reçu du coté client est parfois bien plus gros que 4016 mais surtout, qu’il est parfois trop petit pour être contenu dans ma variable. En effet en envoyant plusieurs trames à la suite, il arrive que celles-ci s’accumulent dans le buffer et du coup, sa taille s’en trouve souvent multipliée par 2.
    La solution est donc de forcer la lecture du buffer avec la taille adéquate à ma variable de type T_Trame_server.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Socket.ReceiveBuf(ma_trame_serveur,taille_bloc+16);
    Mais la, ho surprise, le socket me régénère automatiquement un OnRead pour me signaler qu’il reste des données dans le buffer.
    Ca m’a bien arrangé car j’ai pu lire bout par bout le buffer. Mais par la suite, lorsque je reçois des données trop petites, ne sachant ou les mettre temporairement, il ne me suffit finalement que de simuler une lecteur du buffer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Socket.ReceiveBuf(ma_trame_serveur,0);
    Ce qui à pour effet de laisser les données dans le buffer et de me régénérer un OnRead. Je boucle donc de cette façon jusqu’à ce que le buffer soit d’une taille adéquate pour enfin enclencher la vraie lecture du buffer et les traitements.
    Mais le problème est que la boucle sur l’événement OnRead est très rapide et utilise beaucoup de ressources. J’aimerais pouvoir dire au socket de me générer le prochain OnRead lorsque d’autres données arriveront et non pas tout de suite.


    Bon au finale super ça marche, mais les testes vont me réserver encore des surprises. D’abord, je suis capable de pousser la taille de mon buffer à 8192 octets en local, mais aussi sur internet alors que la taille de la trame Ethernet ne devrait pas dépasser 1500 octets je croyais ! Je pense que TCP fait lui même le travaille de composition et décomposition de paquet mais je ne comprends pas pourquoi il la fait autant varier au début et la rend stable par la suite. En effet lorsque je teste l’application sur le net, les trames sont d’abord toutes différentes, trop petites, trop grandes, pour finalement tendre vers une taille fixe correspondant (miraculeusement) à la taille prévue dans ma variable.

    L’autre surprise que j’ai eue est que lorsque j’envoie plusieurs trames à la suite, au bout d’un certain temps, la réception se bloque. En gros, mes paquets ne peuvent pas se composer de plus de 5 trames sans quoi la 6° n’est jamais reçue. En local, je peux aller jusqu’à 18 trames par paquets mais pas plus. Si je n’acquitte pas au bout de ce nombre de trame, la réception se bloque. Je me demandais si ça n’était pas aussi TCP qui me provoquait ce blocage en réception et si on ne pourrait pas savoir cette limite à l’avance.
    Enfin, l’ordre des trames reste le même alors que je présume, toutes mes trames ne suivent pas le même chemin. Pourtant même si j’envoie 4 trames à la suite, l’ordre sera toujours le bon à l’arrivée alors que ces trames sont indépendantes ! Encore TCP IP ?



    Résumé :
    • [Résolu] 1 – Est-ce bien TCP qui choisit la taille de mes trames envoyées sur internet ?

      [Résolu] 2 – Si oui, comment savoir à l’avance (si c’est possible) le résultat de la négociation avec TCP et la machine ?
      Citation Envoyé par cpdump
      La trame qui circule sur le réseau et sur Internet à une taille d'environ 1500 octets pour le large bande (LAN, ADSL, cable) et dans le 570 pour le RTC, tu peux le modifier dans la base de registre (MTU), mais déconseillé.
      [Résolu]3 – Comment dire au socket de ne pas me générer de OnRead avant la prochaine réception de données tout en gardant le buffer actuel. Ma solution (simuler une lecture) ne me semble pas très propre.
      Citation Envoyé par gord's
      // si dernier message incomplet, le mémoriser
      if debordement then begin
      sizeMemo := sizeTot - cumul;
      bufferMemo := PChar(GAlloc(sizeMemo));
      move(ptrBuffer^,bufferMemo^,sizeMemo);
      Socket.Data := bufferMemo;
      cumul := sizeTot;
      // sinon le traiter
      [Résolu] 4 – Pourquoi au bout d’un certain nombre de trames sans acquittement, la réception se bloque alors que le serveur semble bien avoir émis le paquet. Donc en gros, si je lis, du coté client, plus de 18 Onread ou sur le net, plus de 5 Onread, sans envoyer une donnée quelconque (acquitement ou n'importe quoi) la récéption se bloque. On dirait qu'il faut absolument que j'envoie des données dans mon socket client tous les x secondes ou tous les x paquets, sans quoi, la récéption se bloque. Et je ne comprend pas comment éstimer cette limite (x).

      [Résolu] 5 – Si c’est bien normal, comment savoir la limite de taille des paquets.
      Citation Envoyé par cpdump
      Il y a une fenetre de reception de l'ordre de 64K (appellée RSS ?) définie dans la base registre que l'on peut modifier je crois, mais les modifications des parametres de la pile TCP/IP peuvent être dangereuse.
      [Résolu] 6 – Comment se fait-il que mes trames, envoyées indépendamment les unes des autres arrivent finalement toujours dans le même ordre qu’à l’émission (TCP ? ) ?
      Citation Envoyé par cpdump
      En mode TCP, le flux de donné arrive dans l'ordre dans lequel il est envoyé, c'est le principe même de TCP. Par contre, en mode UDP les paquets sont indépendants et l'ordre n'est pas garanti (même si généralement, ils arrivent dans l'ordre
      [...]
      TCP/IP veut dire TCP au dessus d'IP. Il y a souvent confusion entre les protocoles TCP et IP : IP est un protocole de machine à machine ; Le protocole IP ne garantit pas l'ordre d'arrivée, c'est justement à la couche TCP (protocole de service à service) de faire ce travail et de garantir un flux ordonné.
      [Surement mais ça va mieux]7 - Y a-t-il quelque chose qui je semble ne pas avoir saisi sur les transfères de fichier ou le principe du TCP/IP ?


    Voilà, désolé pour la longueur du post mais ça méritait une légère mise en contexte. [fautes corrigées]

  2. #2
    Expert confirmé

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Par défaut
    1 - Je coirs oui, mais logiquement c'est transparent.

    2 - Comme dit plus, logiquement ce n'est pas ton problème.

    3 - Tester la longueur reçue ( ReceiveLength ) avant de lire le buffer, ne lire le buffer que quand la taille est suffisante.

    4/5 - Qu'entends-tu par acquitement ? La réponse cu client ? Attention, la taille interne des sockets est limitée. Il est possible que ça sature. La logique veut que c'est à toi de stopper l'envoi si le client n'est pas prêt à recevoir tes données. Dans l'exemple donné sur mon site, le pacquet suivant n'est envoyé qu'a réception de l'acquitement. C'est plus long mais plus sécurisé.

    6 - Je ne vois pas ce que tu veux dire, si tu envoies les trames dans un certain ordre, elles arrivent dans le même ordre, encore heureux !

    7 - Le principe de TCP/IP est de s'échanger des blocs, libre à topi de les gérés comme tu veux. Mais la logique d'un échange, est d'attendre la réponse avant de continuer.
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  3. #3
    rgz
    rgz est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 14
    Par défaut
    Heu nan là NoNo tu te trompes je pense.

    3 - Bien évidemme,t, je vérifie la taille du buffer, mais si la taille est trop petite et que je ne lis pas comme tu dis, le socket se bloque et ne reçoit plus. Il lui faut une sorte de validation de récéption: C'est à dire une lecture du buffer (meme si je lis 0 octet de données), il me faut lire sinon plus aucun OnRead ne sera généré.

    4 - Oui, l'acquitement et une réponse du client pour confirmer la récéption d'un paquet (ou trame plustot dans ce cas). j'ai regardé ton exemple. Mais toi, comme tu dis, tu acquites tous les paquets, ce qui n'est pas forcement une solution des plus propre. En effet, le socket à bien une limite, mais elle n'est pas atteinte puisque en local ça passe, ça n'est donc pas le socket qui limite mais le Wanadoo ou un routeur quelconqie sur le net.


    C'est plus long mais plus sécurisé.
    Heuu, non pas vraiment, je les acquite toujours tot ou tard, mais je ne coupe pas le serveur "dans son élant" en fait.


    6 - Je ne vois pas ce que tu veux dire, si tu envoies les trames dans un certain ordre, elles arrivent dans le même ordre, encore heureux !
    Erf, attention à ce que tu dis !!! C'est completement faux ! Relis le passage TCP/IP de ton livre de chevet. le principe de l'internet est que IP va permettre de diviser tes paquets s'ils sont trop gros et donc, à l'arrivée, il te les reconstitue... dans l'ordre bien sur. Mais là, je parle de plusieurs trames, de plusieurs buffers envoyés l'un aprés l'autre. Ils sont donc indépendants, et donc, ne sont pas obligés d'étre reçus dans l'ordre, au contraire, attention à ce que tu affirmes !! :/


    7 - Le principe de TCP/IP est de s'échanger des blocs, libre à toi de les gérés comme tu veux. Mais la logique d'un échange, est d'attendre la réponse avant de continuer.
    La réponse de quoi ? du client ? Et la réponse à combien d'octets ? 2000 ... 20000 ? Le tcp permet en effet d'échanger des bloques, mais aucune logique n'est associée à tcp... Des actions sont faisables et d'autres non, des limites sont mises en place dynamiquement d'autre de façon statique. L'utilisation que t'en fait aprés doit etre adapté à ces régles... et donc rien ni personne ne demande d'acquitter toutes les trames d'un paquet, surtout pas TCP, nien au contraire...


    Pour revenir à mon 1, j'ai trouvé un petit truc qui explique un peu ça. Et au finale, c'est bien une négociation entre la machine et le routeur suivant mais, cette négociation depend à la fois, de la bande passante, de la distance que va parcourir la trame (fiabilité) mais aussi de la capacité de ta machine ! En gros avec un SX400, tu n'envérras jamais une trame de plus de 400 Octects meme si t'es connécté chez ton voisin, qui est provideur...

    Là, ya quelque incimprehension je pense NoNo. De plus, tu remarqueras que ton exemple de programme ne fonction pas sur le net, puisque tu considéres qu'un trame plus petite que la taille prévue est la fin du fichier. hors, comme je l'ai expliqué précédemment, il arrive que la trame se soit divisée un bloc de tailles plus réduites (Via tcp toujours) et donc, tu risques de finaliser ton fichier à la récéption de ton premier bloc meme.

    Bref, il ne semble pas qu'une réponse valable me soit apportée, sans vouloir t'offenser NoNo.

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 298
    Par défaut Re: [Socket] Buffer et TCP
    Citation Envoyé par rgz
    1 – Est-ce bien TCP qui choisit la taille de mes trames envoyé sur internet ?

    2 – Si oui, comment savoir à l’avance (si c’est possible) le résultat de la négociation avec TCP et la machine ?

    3 – Comment dire au socket de ne pas me générer de OnRead avant la prochaine réception de données tout en gardant le buffer actuel. Ma solution (simuler une lecture) ne me semble pas très propre.

    4 – Pourquoi au bout d’un certains nombre de trames sans acquittement, la réception se bloque alors que le serveur semble bien avoir émis le paquet.

    5 – Si c’est bien normal, comment savoir la limite de taille des paquets.

    6 – Comment ce fait-il que mes trames, envoyées indépendamment les unes des autres arrivent finalement toujours dans le même ordre qu’à l’émission (TCP ? ) ?

    7 - Y a-t-il quelque chose qui je semble ne pas avoir saisi sur les transfère de fichier ou le principe du TCP/IP ?[/list]

    Voilà, désolé pour la longueur du post mais ça méritait un légère mise en contexte.
    1) La trame qui circule sur le réseau et sur Internet à une taille d'environ 1500 octets pour le large bande (LAN, ADSL, cable) et dans le 570 pour le RTC, tu peux le modifier dans la base de registre (MTU), mais déconseillé.

    2) cf. 1)

    3) Je suis pas certain d'avoir compris le problème. Comme le paquet qui circule est inférieur à ton buffer il faut plusieurs paquets donc plusieurs OnRead. Est ce un problème ? sinon tu peux peut être utiliser le fragment flag mais je ne me souviens plus.

    5) cf. 1)

    6) En mode TCP, le flux de donné arrive dans l'ordre dans lequel il est envoyé, c'est le principe même de TCP. Par contre, en mode UDP les paquets sont indépendants et l'ordre n'est pas garanti (même si généralement, ils arrivent dans l'ordre)

  5. #5
    rgz
    rgz est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 14
    Par défaut Re: [Socket] Buffer et TCP
    Citation Envoyé par cpdump
    3) Je suis pas certain d'avoir compris le problème. Comme le paquet qui circule est inférieur à ton buffer il faut plusieurs paquets donc plusieurs OnRead. Est ce un problème ?
    oui, le probléme est qu'il me faut absolument lire dans le buffer lors d'un évenement OnRead sans quoi, la récéption suivante ne va pas me générer de OnRead. D'où le ReadBuffer(Trame,0). J'aimerais pouvoir ne rioen lire du tout et attendre la suite, la aucun probleme, mais si je ne répond pas par un readbuffer dans mon OnRead, tout se bloque, en récéption.

    Pour le 1 et le 2, ok, j'ai compris.
    pour le 6, ok aussi, je ne savais pas que les données arrivent toutjours dans le meme ordre... rien que de le dire, ça me parait bizarre, mais bon, ok.

    Merci à toi cpdump .

    Ma partie 5, si je me fie à NoNo, serai dut au fait que le buffer à une limite "d'empilation", qu'il ne peut recevoir plus de x octet à la suite sans acquitement. mais comment savoir la valeur de se X, qui varie celon les connections et les machines ? De plus, m'acquitement n'est en réalité qu'un paquet envoyé par le client, mais tcp, à mon avis, ne sait pas que c'est un acquitement, à moins qu'il soit super intelligent... mais je pense pas. Mo, acquitement n'est qu'un buffer envoyé par le client, et est un acquitement au niveau de la récéption et du traitement.
    Donc en gros, si je lis, du coté client, plus de 18 Onread ou sur le net, plus de 5 Onread, sans envoyer une donnée quelconque (acquitement ou n'importe quoi) la récéption se bloque. On dirait qu'il faut absolument que j'envoie des données dans mon socket client tous les x secondes ou tous les x paquets, sans quoi, la récéption se bloque. Et je ne comprend pas comment éstimer cette limite (x).

    Mais c'est déjà un peu plus clair, merci.

  6. #6
    Membre éprouvé Avatar de gord's
    Inscrit en
    Avril 2003
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 115
    Par défaut
    voila un exemple de lecture socket
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
     
    procedure TServiceCom.doRead(tp, id: integer; Socket: TCustomWinSocket);
    var
        bufferLu    : PChar  ; // buffer contenant le message lu
        sizeLue     : integer; // taille effectivement lue
        bufferMemo  : PChar;   // buffer mémorisé au tour précédent si débordement
        sizeMemo    : integer; // taille de ce buffer mémorisé
        bufferTot   : PChar;   // concaténation de bufferLu et bufferMemo
        sizeTot     : integer; // taille totale des datas à traiter
        ptrBuffer   : PChar;   // pointeur qui parcourt le bufferTot
        size        : integer; // taille attendue du message courant
        cumul       : integer; // cumul tailles messages traités
        debordement : boolean; // indique si le message en cours est incomplet
        traducDone  : boolean; // passage de index lstSck à Ident : le faire une seule
                                  // fois quand boucle sur plusieurs messages !
        function LireBuf(var sz: integer) : PChar;
        var
            szlue : integer;
            p1,p2 : PChar  ;
        begin
            sz := socket.ReceiveLength;
            p1 := PChar(GAlloc(sz));
            szlue := Socket.ReceiveBuf(p1^, sz);
     
            if szlue > 0 then begin
                if szlue < sz then begin
                    p2 := PChar(GAlloc(szlue));
                    move(p1^,p2^,szlue);
                    GFree(p1);
                    sz     := szlue;
                    result := p2;
                end else
                    result := p1;
            end else begin
                GFree(p1);
                sz := 0;
                result := nil;
            end;
        end;
     
        procedure Concatener(p1: PChar; l1: integer;
                             p2: PChar; l2: integer;
                             out px: PChar; out lx: integer);
        begin
            px := PChar(GAlloc(l1+l2));
            move(p1^, px^    ,l1);
            move(p2^,(px+l1)^,l2);
            lx := l1+l2;
            try GFree(p1); finally end;
            try GFree(p2); finally end;
        end;
     
        procedure traiterMessage(msg: Pchar; siz: integer);
        // id est l'identifiant de socket client
        // par convention, le client m'envoie une première chaine d'identification
        // juste apres l'ouverture de socket
        // ça me permet d'avoir plusieurs clients sur la même machine
        var
            buf : PChar;
        begin
            if id<0 then begin      // premier read coté serveur
                getmem(buf,siz+1);
                move(msg^, buf^, siz);
                buf[siz]:=#0;
                // on update id pour le cas où 2ème msg arrivé en même temps
                id := connectSocket(socket, tp, string(buf));
                freemem(buf);
            end
            else begin
                // attention, on passe plusieurs fois ici si plusieurs messages ...
                if not traducDone then begin
                    id := Index2Ident(tp, id);
                    traducDone := true;
                end;
                if (id>=0) then begin
                    buf := PChar(GAlloc(siz));
                    move(msg^, buf^, siz);
                    // ICI, traitement applicatiff du message reçu 'buf'
                end
                else
                    Log('DoRead type inconnu:'+IntToStr(tp)+' ignoré');
            end;
        end;
     
    begin
        // lecture dans la socket (en sortie, sizeLue = taille rééllement obtenue)
        bufferLu := LireBuf(sizeLue);
        if sizeLue > 0 then begin
     
            // récupération d'un éventuel message incomplet du tour précédent
            if Socket.Data = nil then begin
                bufferTot := bufferLu;
                sizeTot   := sizeLue;
            end else begin
                bufferMemo  := socket.Data;
                sizeMemo    := GSize(HGlobal(bufferMemo));
                Socket.Data := nil;
                Concatener(bufferMemo, sizeMemo,
                           bufferLu  , sizeLue ,
                           bufferTot , sizeTot );
            end;
     
            // analyse du buffer : découpage en messages
            // chaque message émis est précédé d'un integer indiquant sa taille
            ptrBuffer := bufferTot;
            cumul     := 0;
            size      := 0;
            traducDone:= false;
            while cumul < sizeTot do begin
                // taille du message à recevoir
                if (sizeTot-cumul) >= sizeof(integer) then begin
                    size        := (Pinteger(ptrBuffer))^;
                    debordement := (cumul+size) > sizeTot;
                end else
                    debordement := true;
     
                // si dernier message incomplet, le mémoriser
                if debordement then begin
                    sizeMemo   := sizeTot - cumul;
                    bufferMemo := PChar(GAlloc(sizeMemo));
                    move(ptrBuffer^,bufferMemo^,sizeMemo);
                    Socket.Data := bufferMemo;
                    cumul := sizeTot;
                // sinon le traiter
                end else begin
                    if (size>sizeof(integer)) then // si = , c'est le polling client
                        traiterMessage(PChar(ptrBuffer+sizeof(integer)),
                                       size-sizeof(integer));
                    ptrBuffer := ptrBuffer + size;
                    cumul     := cumul     + size;
                end;
     
            end; // while cumul < sizeTot
     
            try GFree(bufferTot); finally  end;
     
       end; // if sizeLue>0
     
    end;

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 298
    Par défaut Re: [Socket] Buffer et TCP
    [quote="rgz"]
    Citation Envoyé par cpdump

    Ma partie 5, si je me fie à NoNo, serai dut au fait que le buffer à une limite "d'empilation", qu'il ne peut recevoir plus de x octet à la suite sans acquitement. mais comment savoir la valeur de se X, qui varie celon les connections et les machines ? De plus, m'acquitement n'est en réalité qu'un paquet envoyé par le client, mais tcp, à mon avis, ne sait pas que c'est un acquitement, à moins qu'il soit super intelligent... mais je pense pas. Mo, acquitement n'est qu'un buffer envoyé par le client, et est un acquitement au niveau de la récéption et du traitement.
    Donc en gros, si je lis, du coté client, plus de 18 Onread ou sur le net, plus de 5 Onread, sans envoyer une donnée quelconque (acquitement ou n'importe quoi) la récéption se bloque. On dirait qu'il faut absolument que j'envoie des données dans mon socket client tous les x secondes ou tous les x paquets, sans quoi, la récéption se bloque. Et je ne comprend pas comment éstimer cette limite (x).

    Mais c'est déjà un peu plus clair, merci.
    Il y a une fenetre de reception de l'ordre de 64K (appellée RSS ?) définie dans la base registre que l'on peut modifier je crois, mais les modifications des parametres de la pile TCP/IP peuvent être dangereuse.

    pour le 6, ok aussi, je ne savais pas que les données arrivent toutjours dans le meme ordre... rien que de le dire, ça me parait bizarre, mais bon, ok.
    TCP/IP veut dire TCP au dessus d'IP. Il y a souvent confusion entre les protocoles TCP et IP : IP est un protocole de machine à machine ; Le protocole IP ne garantit pas l'ordre d'arrivée, c'est justement à la couche TCP (protocole de service à service) de faire ce travail et de garantir un flux ordonné.

  8. #8
    rgz
    rgz est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 14
    Par défaut
    Merci à tous pour toutes ces informations. ( cpdump )

Discussions similaires

  1. server de sockets unix et tcp/ip en mm tps?
    Par iznogoud36 dans le forum Linux
    Réponses: 7
    Dernier message: 02/01/2007, 08h58
  2. [SOCKET] - Buffer & Read() ou Recv()
    Par jacquesh dans le forum C++
    Réponses: 14
    Dernier message: 27/04/2006, 10h42
  3. Socket : UDP ou TCP
    Par lafracas dans le forum Développement
    Réponses: 2
    Dernier message: 10/04/2006, 22h43
  4. code c pour sockets (udp vers tcp et inversement)
    Par HiT dans le forum Développement
    Réponses: 11
    Dernier message: 19/11/2005, 18h03
  5. raw socket et protocole TCP/IP
    Par robertmouac dans le forum Développement
    Réponses: 3
    Dernier message: 09/03/2005, 23h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo