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 :

Utiliser les Streams avec TSocket


Sujet :

Web & réseau Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2005
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2005
    Messages : 52
    Points : 61
    Points
    61
    Par défaut Utiliser les Streams avec TSocket
    Salut à tous,

    Il est possible d'utiliser les Streams avec les composants TidTCP d'Indy. Cependant ils ne sont pas tres souples d'utilisation. Je pense que l'on doit pouvoir faire de même avec les composants TSocket en effet la fonction SendStream existe. Mais pour son homologue ReceiveStream ce n'est pas le cas. Sauriez vous comment faire ?

    Merci à vous

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2002
    Messages : 685
    Points : 1 582
    Points
    1 582
    Par défaut
    Qu'entends tu par "pas très souples d'utilisation" ?... Les composants Indy sont de loin bien mieux conçus que les TClientSocket/TServerSocket.

    Pour ta réponse, si ReceiveStream() n'existe pas côté serveur, tu peux aussi lire le stream avec ReceiveBuf().
    "It's more fun to compute !"

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2005
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2005
    Messages : 52
    Points : 61
    Points
    61
    Par défaut
    Re,

    Quand je disais pas très souple je m'explique : Effectivement les composants Indy sont mieux faits dans la mesure ou il y a moins d'erreurs. Cependant niveau client tu n'as pas de procedure OnRead ce qu'il fait que c'est un sacré problème : Rien que pour faire un tchatte par exemple.

    J'ai réalisé ce code :

    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
     Procedure TForm1.SendStreamTo (Who : TSocket; AStream : TStream);
    Var
    Buffer
    Begin
    If AStream<>nil then 
    begin
    AStream.seek(0,SoFromBeginning);
    Try
    GetMem(Buffer,AStream.size);
    AStream.Read(Buffer^,AStream.size);
    Who.send(Buffer^,AStream.Size);
    finally
    FreeMem(Buffer);
    end;
    end;
    end;
    --------

    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
     Procedure TForm1.ReceiveStreamFrom(Who : TSocket;AStream : TSream);
    Var
    Buffer : Pointer
    Len : longInt;
    Begin
    Len:=Who.ReceiveLength;
    If Len<>0 then 
    begin
    try
    GetMem(Buffer,Len);
    Who.ReceiveBuf(Buffer^,len);
    Astream.Write(Buffer^,Len);
    Finally
    FreeMem(Buffer);
    end;
    end;
    end;
    Manque de chance : cela se traduit par un plantage du socket. Je ne sais pas pourquoi

    Merci pour ta réponse

  4. #4
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 50
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : juin 2004
    Messages : 2 932
    Points : 3 504
    Points
    3 504
    Par défaut
    Salut

    Tout d'abord...



    Ensuite :
    Ce fil de discussion peut-il t'aider à y voir clair ?
    http://www.developpez.net/forums/sho...7&postcount=10

    Pour faire un Tchat, les méthodes SendText et ReceiveText ne te suffisent-elles pas ?

    Enfin, tu as oublié de définir ce qu'était Buffer dans la déclaration de variables de SendStreamTo

    Procedure TForm1.SendStreamTo (Who : TSocket; AStream : TStream);
    Var
    Buffer //<---- ici
    Begin
    Enfin, il est fortement probable que tu soit en mode non-bloquant, auquel cas, ton FreeMem intervient alors que le socket n'a pas fini d'utiliser les données du buffer et là, ça coince...
    Bidouilleuse Delphi

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2005
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2005
    Messages : 52
    Points : 61
    Points
    61
    Par défaut
    Désolé pour les balises : autant pour moi.

    Pour le buffer : je n'ai pas Delphi sous les yeux donc j'ai justre réécrit de tete ce que j'ai fais hier soir. Effectivement Buffer est un Pointeur.

    Je suis en mode non bloquant : cela veut il dire que je dois mettre un sleep ou il y a t'il un autre moyen ?

    Merci

  6. #6
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 50
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : juin 2004
    Messages : 2 932
    Points : 3 504
    Points
    3 504
    Par défaut
    Je pense effectivement qu'un sleep devrait faire l'affaire, mais tu perds du coup l'intérêt du non bloquant.

    mais je me suis peut-être avancé un peu sur ma supposition puisque lors du SendBuf, Delphi effectue un Lock puis un UnLock dans son code (une espèce de pause des threads si j'ai bien compris)...

    Sinon, à la réception, il est possible que tu ne reçoive pas tout ton paquet de données en un seul morceau.

    En tout cas, Borland n'a pas réussi à implémenter les Streams en mode non-bloquant, si on en croit les fichiers d'aide.

    Ce qui est sur, c'est que si tu n'as pas tant de connexions que ça et que le traffic n'est pas très intensif, peut-être serait-il mieux de tout gérer en bloquant.

    Là s'arrètent mes compétences en ce domaine
    Bidouilleuse Delphi

  7. #7
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    3 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : mai 2002
    Messages : 3 077
    Points : 5 127
    Points
    5 127
    Par défaut
    salut


    a priorie le receivebuffer attend en paramettre un tableau de char de type TIdBytes

    voila la definition dans IdGlobal
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      TBytes = array of Byte;
      {$ENDIF}
      TIdBytes = TBytes;
    essai avec ce type plutot que d'utiliser un pointeur
    ensuite si l'erreur persiste donne nous le type d'erreur declencher


    @+ Phil
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2005
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2005
    Messages : 52
    Points : 61
    Points
    61
    Par défaut
    Re,

    Effectivement les streams ne fonctionnent pas semble t'il en mode non bloquant d'un point de vue de la réception. C'est bien dommage car les composants Indy ne sont pas top : il est difficile de faire receptionner rien qu'un texte par le client depuis le serveur. Je vais donc me rabattre sur un mode bloquant.

    Merci à vous

  9. #9
    Membre expérimenté

    Profil pro
    Inscrit en
    octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2002
    Messages : 685
    Points : 1 582
    Points
    1 582
    Par défaut
    les composants Indy ne sont pas top : il est difficile de faire receptionner rien qu'un texte par le client depuis le serveur
    Si, si, c'est possible. Certes, Indy pour faire un chat, c'est pas forcément top parce que c'est plus le modèle non bloquant qui s'impose, mais ca peut aussi se faire sans trop de mal.

    Par exemple, on embarque la réception dans un thread :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    While AClient.Connected do
    begin
      S := AClient.ReadLn();
      NotifyTextReceived(AClient, S); //Notifier la reception d'un texte au thread principal.
    end;
    ... et l'emission dans un autre.

    Sinon, les composants ICS marchent aussi très bien :-)
    "It's more fun to compute !"

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/02/2007, 18h47
  2. Comment utiliser le streaming avec en .flv
    Par pierrot10 dans le forum Flash
    Réponses: 3
    Dernier message: 21/10/2006, 17h38
  3. comment utiliser les API avec Perl?
    Par megapacman dans le forum Langage
    Réponses: 5
    Dernier message: 23/08/2006, 15h18
  4. [CF][PPC/VB.NET] Comment utiliser les Socket avec Pocket PC ?
    Par joefou dans le forum Windows Mobile
    Réponses: 5
    Dernier message: 17/05/2005, 14h24

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