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 :

#0 obligatoire avec winsock ?


Sujet :

Web & réseau Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 168
    Par défaut #0 obligatoire avec winsock ?
    Bonjour,

    Je désirais savoir si lorsque l'on utilise les API Winsock et que l'on effectue un send() si il est obligatoire de mettre un #0 a la fin de la chaîne a envoyer ?

    Parce que j'ai remarqué dans certains cas, a la fin d'un texte envoyer (lors de la réception) il y a un caractère qui ne devrais pas être la.

    Si j’insère le #0 il n’apparaît pas..

    Il me semblait que Delphi géré automatiquement cela.

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    send() selon la MSDN, on lui passe la taille du buffer donc le zéro n'a pas de conséquence à l'envoie
    Heureusement, sinon on ne pourrait pas envoyer des record sérialisé si il y avait une gestion par zéro terminal (justement un bug du TCP\IP à l'époque de Windev 7.0)

    Ensuite, pour la réception avec recv, c'est le même principe, on indique la taille du buffer mais surtout il renvoie le nombre d'octet réellement écrit !
    C'est peut-être la ton erreur, tu utilise un StrPas ou un assimilé String\AnsiString implicite alors qu'il faut bien s'arrêter au nombre d'octet lu !

    Evite le type string, préfere le type Windows.BYTE ou array of Byte, des buffers sans risque en XE2 !

    surtout qu'en Delphi, le paramètre est un buffer non typé donc pas d'histoire de chaine à zéro terminal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    function send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    function recv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 168
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    send() selon la MSDN, on lui passe la taille du buffer donc le zéro n'a pas de conséquence à l'envoie
    Heureusement, sinon on ne pourrait pas envoyer des record sérialisé si il y avait une gestion par zéro terminal (justement un bug du TCP\IP à l'époque de Windev 7.0)

    Ensuite, pour la réception avec recv, c'est le même principe, on indique la taille du buffer mais surtout il renvoie le nombre d'octet réellement écrit !
    C'est peut-être la ton erreur, tu utilise un StrPas ou un assimilé String\AnsiString implicite alors qu'il faut bien s'arrêter au nombre d'octet lu !

    Evite le type string, préfere le type Windows.BYTE ou array of Byte, des buffers sans risque en XE2 !

    surtout qu'en Delphi, le paramètre est un buffer non typé donc pas d'histoire de chaine à zéro terminal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    function send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    function recv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    Ok je te remercie

  4. #4
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 168
    Par défaut
    Encore une petite question cependant;

    Lorsque j'ai reçu mon paquet dans un array of byte

    C'est safe de le convertir dans un String sous XE ? (sachant que mon client est en ANSI (Delphi 2007) et le Server (XE2) donc Wide)

    Sous XE buff = String, len = integer, arrBytes = Array Bytes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SetLength(buff, len);
    MoveMemory(@buff[1],@arrBytes[0], len);

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    N'ai je pas déjà répondu ?

    Citation Envoyé par ShaiLeTroll Voir le message
    Evite le type string, préfere le type Windows.BYTE ou array of Byte, des buffers sans risque en XE2 !
    Utilise RawByteString à la limite, le mieux étant un TMemoryStream ou un PByte !

    Tu sais pourtant que XE2 c'est en Unicode, prenons ton code, et voyons l'énorme erreur qu'il contient !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SetLength(buff, len);
    MoveMemory(@buff[1],@arrBytes[0], len);
    SetLength compte en caractère, tu vas donc créer une chaine de len caractères, ce qui donne len * 2 octets
    Ensuite tu copie len octets par MoveMemory, donc au final, tu as la moitié de la chaine qui n'est pas rempli et une première moitié qui contiendra des caractères unicode problablement du chinois !

    Oublie les String pour la manipulation d'octets, c'était une pratique possible en Delphi ANSI même si un peu dégueux mais maintenant c'est tout simplement dangereux !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 934
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 934
    Par défaut
    Si tu t'occupes du client et du serveur, il n'y a pas de problème à passer des chaînes. Il faut simplement bien spécifier une taille en octet !
    Je suis justement en train de le tester sur des Pipes.

    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
    const
      BufferSize = 4096;
     
    procedure TNamedPipeDialogThread.Execute;
    var
      Data  :string;
      Count :cardinal;
     
    begin
      while not Terminated do
      begin
        SetLength(Data, BufferSize div SizeOf(Char));
     
        if ReadFile(Pipe, Data[1], BufferSize, Count, nil) then
        begin
          if Count > 0 then
          begin
            SetLength(Data, Count div SizeOf(Char));
     
            Synchronize(procedure
                        begin
                          if Assigned(Server.OnData) then
                            Server.OnData(Data);
                        end);
     
            if not WriteFile(Pipe, Data[1], Length(Data) *SizeOf(Char), Count, nil) then Break;
          end;
        end
        else Break;
      end;
     
      FlushFileBuffers(Pipe);
      DisconnectNamedPipe(Pipe);
      CloseHandle(Pipe);
    end;

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Si tu t'occupes du client et du serveur, il n'y a pas de problème à passer des chaînes. Il faut simplement bien spécifier une taille en octet !
    Si les deux sont en XE2 ça fonctionne mais ce n'est pas le cas :
    Citation Envoyé par 0x44-0x43-0x53-0x43 Voir le message
    C'est safe de le convertir dans un String sous XE ? (sachant que mon client est en ANSI (Delphi 2007) et le Server (XE2) donc Wide)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 934
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 934
    Par défaut
    Ah oui, pas fait attention

    Mais bon, définir le buffer en AnsiString et faire Result{string}=Buffer{ansistring} est encore plus simple

Discussions similaires

  1. erreur avec winsock
    Par Quality_Design dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 25/03/2006, 12h47
  2. [VB]Envoie de fichier avec winsock
    Par Xdrei dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 24/03/2006, 09h54
  3. Envoie de 2 variables avec winsock puis traitement
    Par Xdrei dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 18/03/2006, 10h27
  4. Envoyer des pieces jointes avec winsock....
    Par YoUpIeN dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 24/01/2005, 00h26
  5. tri obligatoire avec DISTINCT?
    Par Marseillais9 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 31/07/2003, 17h50

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