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

 Delphi Discussion :

Delphi Embarcadero Seattle, Probleme Multithreaded Winsock


Sujet :

Delphi

  1. #1
    Membre du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut Delphi Embarcadero Seattle, Probleme Multithreaded Winsock
    Bonjour tout le monde, j'ai un petit souci avec Embarcadero, je n'arrive pas à crier un socket deuo au problème dans String-To-Pansichar, bien sûr passer par "thread param"
    voici mon exemple :

    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
     
    type
     _TMasterConnectionData = packed record
       RemoteHost:String;
       RemotePort:Integer;
       Socks4Host:string;
       Socks4Port:Integer;
       bUsesProxy:Boolean;
       bAdminPriv:Boolean;
       bProtected:Boolean;
       bPersistSocks:Boolean;
       ThreadType:Byte;
       TimeWait:Integer;
       TimeOut:Integer;
       wUserName:WideString;
       wPassword:WideString;
    end;
    TMasterConnectionData=_TMasterConnectionData;
    PTMasterConnectionData=^TMasterConnectionData;
     
    function SetupMasterThread(
      RemoteHost:String;
      RemotePort:Integer;
      Socks4Host:string;
      Socks4Port:Integer;
      bUsesProxy:Boolean;
      bAdminPriv:Boolean;
      bProtected:Boolean;
      bPersistSocks:Boolean;
      ThreadType:Byte;
      TimeWait:Integer;
      TimeOut:Integer;
      wUserName:WideString;
      wPassword:WideString):Boolean;
    var
      dwThreadID:Cardinal;
      hThread:Thandle;
      MasterConnectionData:TMasterConnectionData;
    begin
      Result := False;
      FillChar(MasterConnectionData , SizeOf(TMasterConnectionData) ,#0);
      MasterConnectionData.RemoteHost := RemoteHost;
      MasterConnectionData.RemotePort := RemotePort;
      MasterConnectionData.Socks4Host := Socks4Host;
      MasterConnectionData.Socks4Port := Socks4Port;
      MasterConnectionData.bUsesProxy := bUsesProxy;
      MasterConnectionData.bAdminPriv := bAdminPriv;
      MasterConnectionData.bProtected := bProtected;
      MasterConnectionData.bPersistSocks := bPersistSocks;
      MasterConnectionData.ThreadType := ThreadType;
      MasterConnectionData.TimeWait := TimeWait;
      MasterConnectionData.TimeOut  := TimeOut;
      MasterConnectionData.wUserName := wUserName;
      MasterConnectionData.wPassword := wPassword;
      try
        hThread := CreateThread(nil, 0, @MasterConnectionThread, @MasterConnectionData, 0, dwThreadID);
        WaitForSingleObject(hThread, 500);
      finally
       CloseHandle(hThread);
       Result := True;
      end;
    end;
     
    ...........
    var
     szHost,szProxyHost:String;
    .......
    begin
          SetupMasterThread(szHost,Configuration.Port,szProxyHost,Configuration.ProxyPort,
          Configuration.UsesProxy,TRUE,Configuration.PasswordProtect,Configuration.hijakProxy,MASTER_THREAD_SETUP_NOTIFICATION,
          Configuration.Interval,Configuration.TimeOut,WideString(Configuration.UserID),WideString(Configuration.Password));
    ..............
      etc .....
     
    function MasterConnectionThread(pData:Pointer):Integer; stdcall; // biensur declarer comme : forward;
    var
       RemoteHost, Socks4Host:string;
    ..... etc ...
       ConnectionAddress:Pansichar;
    ....
    begin
      RemoteHost := PTMasterConnectionData(pData)^.RemoteHost;
      RemotePort := PTMasterConnectionData(pData)^.RemotePort;
      Socks4Host := PTMasterConnectionData(pData)^.Socks4Host;
      Socks4Port := PTMasterConnectionData(pData)^.Socks4Port;
    ... etc etc
      if ( bUsesProxy = True ) then
      begin
        ConnectionAddress := Pansichar(Socks4Host);
     
      NetSocket := socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
      NetSockAddr.sin_family := AF_INET;
      NetSockAddr.sin_port := htons(ConnectionPort);
      NetSockAddr.sin_addr.S_addr := inet_addr(ConnectionAddress);
      //NetHostEnt := gethostbyaddr(@NetSockAddr.sin_addr.S_addr, 4, AF_INET);
      if ( NetSockAddr.sin_addr.S_addr = INADDR_NONE ) then
      begin
        NetHostEnt := Gethostbyname(ConnectionAddress);
     
    .......................................... etc ... etc
    Ça ne fonctionne pas, je ne peux pas réussir à me connecter avec Embarcadero, mais par contre sur Delphi7 sa fonctionne très bien.
    J'ai essayé de mettre application console pour visualiser, et quand je fais Write Ln(Connection Address); il m'affiche 1, donc a ce que je vois quil na par reussi à charger complètement le string dans pansichar;

    -Si quelqu'un a une idée ?? merci d'avance.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Delphi Seattle n'est plus Ansi par Défaut mais Unicode donc votre chaine Socks4Host contient des données UTF16
    C'est le cas depuis Delphi 2009, soit plus de dix ans.

    Il y a un avertissement à la compilation qui doit avertir d'une conversion douteuse de Socks4Host
    Habituez vous à n'avoir jamais aucun conseil ni avertissement, cela permet de tout de suite constater une anomalie de ce type.

    La correction est très simple, il faut faire un conversion explicite du string (UnicodeString) en AnsiString avant d'en récupérer le pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ConnectionAddress := PAnsiChar(AnsiString(Socks4Host));

    le packed ne sert pas à grand chose dans votre cas, cela serait important si vous le serialisiez.
    Vous pourriez utiliser un TThread et faire une programmation Objet qui rendrait votre code bien plus simple (pas de pointeur)
    Par exemple WaitForSingleObject devrait être dans une boucle, le TimeOut régulier permet d'appeler par exemple Application.ProcessMessages pour que l'application ne soit pas gelée
    Dans votre exemple, le thread ne sert pas à grand chose puisque vous bloquer immédiatement le thread principal, est-ce une tentative d'un ConnectTimeOut manuel ?
    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 du Club

    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2008
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 33
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Delphi Seattle n'est plus Ansi par Défaut mais Unicode donc votre chaine Socks4Host contient des données UTF16
    C'est le cas depuis Delphi 2009, soit plus de dix ans.

    Il y a un avertissement à la compilation qui doit avertir d'une conversion douteuse de Socks4Host
    Habituez vous à n'avoir jamais aucun conseil ni avertissement, cela permet de tout de suite constater une anomalie de ce type.

    La correction est très simple, il faut faire un conversion explicite du string (UnicodeString) en AnsiString avant d'en récupérer le pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ConnectionAddress := PAnsiChar(AnsiString(Socks4Host));

    le packed ne sert pas à grand chose dans votre cas, cela serait important si vous le serialisiez.
    Vous pourriez utiliser un TThread et faire une programmation Objet qui rendrait votre code bien plus simple (pas de pointeur)
    Par exemple WaitForSingleObject devrait être dans une boucle, le TimeOut régulier permet d'appeler par exemple Application.ProcessMessages pour que l'application ne soit pas gelée
    Dans votre exemple, le thread ne sert pas à grand chose puisque vous bloquer immédiatement le thread principal, est-ce une tentative d'un ConnectTimeOut manuel ?
    Merci mon ami, c'est résolu à cause de toi, j'ai essayé avant par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ConnectionAddress = PansiChar(String(Socks4Host));
    mais ne pas marcher !, je viens de migrer sur Seattle, CAUSE 64bit et Android Compilation,

    -- Pour le timeOut, j'ai utilisé :
    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
     
     
     ....... etc ........
     if FDS.fd_count < FD_SETSIZE then
      begin
        FDS.fd_array[FDS.fd_count] := dwSocket;
        Inc(FDS.fd_count);
      end;
      NetSocket := Select(0, @FDS, NIL, NIL, @TIME);
      if (NetSocket = SOCKET_ERROR) or (NetSocket = 0) then
      begin
        Time.tv_usec := 0;
        FDS.fd_count := 0;
        Result := True;
        if ( dwSocket = 0 ) or ( dwSocket = -1 ) then Result := True;
    ................
    Dans mon cas je charge des données et je les exécute dans des threads séparer sans attendre que le thread se termine, je ferme que le handle, je termine pas le thread,
    le thread se termine tout seul après le traitement des données ou bien a mon signal, mon application est une application cosole de 30 kilobyte, pas de forme ni VCL etc

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

Discussions similaires

  1. Delphi Embarcadero XE2
    Par manessci dans le forum Débuter
    Réponses: 3
    Dernier message: 15/03/2013, 08h48
  2. Probleme recv() [Winsock]
    Par kernox dans le forum Réseau
    Réponses: 3
    Dernier message: 11/04/2006, 20h58
  3. delphi 2005 perso probleme avec ADO
    Par corvington dans le forum Bases de données
    Réponses: 1
    Dernier message: 16/03/2006, 18h23
  4. Réponses: 1
    Dernier message: 12/02/2006, 17h55
  5. [Delphi 2005 Perso] Probleme déclaration de méthode
    Par alk dans le forum Delphi .NET
    Réponses: 5
    Dernier message: 08/11/2005, 16h19

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