SocketTlsReadAvailable

Lit toutes les données disponibles depuis une connexion TLS sécurisée.

int  SocketTlsReadAvailable(
   int           socket,               // socket
   uchar&        buffer[],             // buffer pour lire les données depuis une socket
   const uint    buffer_maxlen         // nombre d'octets à lire
   );

Paramètres

socket

[in]  Handle de la socket retournée par la fonction SocketCreate. Lorsqu'un handle incorrect est passé à _LastError, l'erreur 5270 (ERR_NETSOCKET_INVALIDHANDLE) est activée.

buffer

[out]  Référence au tableau de type uchar dans lequel les données sont lues. La taille du tableau dynamique est augmentée du nombre d'octets lus. La taille du tableau ne peut pas être supérieure à INT_MAX (2147483647).

buffer_maxlen

[in]  Nombre d'octets à lire dans le tableau buffer[]. Les données ne rentrant pas dans le tableau restent dans la socket. Elles peuvent être lues lors de l'appel suivant à SocketTlsReadAvailable ou à SocketTlsRead. buffer_maxlen ne peut pas être supérieur à INT_MAX (2147483647).

Valeur de Retour

Retourne le nombre d'octets lus en cas de succès. Retourne -1 en cas d'erreur.

Note

Si une erreur se produit sur une socket système lors de l'exécution de la fonction, la connexion établie via SocketConnect est interrompue.

En cas d'erreur de lecture des données, l'erreur 5273 (ERR_NETSOCKET_IO_ERROR) est inscrite dans _LastError.

La fonction ne peut être appelée que depuis les Expert Advisors et les scripts, puisqu'ils sont exécutés dans leurs propres threads d'exécution. Si elle est appelée depuis un indicateur, GetLastError() retourne l'erreur 4014 — "Function is not allowed for call".

Exemple :

//+------------------------------------------------------------------+
//|                                       SocketTlsReadAvailable.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com
#property version     "1.00"
#property script_show_inputs
//+------------------------------------------------------------------+
//| Script inputs                                                    |
//+------------------------------------------------------------------+
input string InpMethod ="GET";            // Method (HEAD,GET)
input string InpServer ="www.google.com"// Server
input uint   InpPort   =443;              // Port
input uint   InpTimeout=5000;             // Timeouts
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(void)
  {
   Print("Server: ",InpServer);
   Print("Port: ",InpPort);
//--- crée une socket et récupère son handle
   const int socket=SocketCreate();
 
   if(socket==INVALID_HANDLE)
     {
      Print("SocketCreate() failed. Error ",GetLastError());
      return;
     }
//--- définit les délais d'attente pour la réception et l'envoi de données pour un objet système socket
   if(!SocketTimeouts(socket,InpTimeout,InpTimeout))
     {
      PrintFormat("SocketTimeouts(%u, %u) failed. Error %d",InpTimeout,InpTimeout,GetLastError());
      SocketClose(socket);
      return;
     }
//--- se connecte à SERVER via le port PORT
   if(!SocketConnect(socket,InpServer,InpPort,InpTimeout))
     {
      PrintFormat("SocketConnect('%s', %u, %u) failed. Error %d",InpServer,InpPort,InpTimeout,GetLastError());
      SocketClose(socket);
      return;
     }
//--- récupère les données sur le certificat utilisé pour sécuriser la connexion réseau
   string   subject,issuer,serial,thumbprint;
   datetime expiration;
 
   if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
     {
      Print("TLS certificate:");
      Print("   Owner:      ",subject);
      Print("   Issuer:     ",issuer);
      Print("   Number:     ",serial);
      Print("   Print:      ",thumbprint);
      Print("   Expiration: ",expiration);
     }
   else
     {
      //--- le serveur ne fournit pas de certificat : signale une connexion non sécurisée et fin
      Print("The connection is not secured by a certificate");
      SocketClose(socket);
      return;
     }
//--- envoie une requête au serveur
   string request=StringFormat("%s / HTTP/1.1\r\nHost: %s\r\nUser-Agent: MetaTrader 5\r\n\r\n",InpMethod,InpServer);
 
   if(HTTPSendTLS(socket,request))
     {
      //--- demande envoyée - récupère la réponse
      Print("\nRequest sent. Starting page loading...");
      uchar response[]; // all received data (document header and body)
 
      if(!HTTPRecvTLS(socket,response,InpTimeout))
        {
         Print("There were errors while reading the page");
         SocketClose(socket);
         return;
        }
      //--- indique le nombre d'octets de données reçus
      PrintFormat("%u bytes received",response.Size());
      //--- affiche uniquement l'en-tête de la page obtenue
      string result    =CharArrayToString(response,0,WHOLE_ARRAY,CP_UTF8);
      int    header_end=StringFind(result,"\r\n\r\n");
 
      if(header_end>0)
        {
         Print("\nHTTP answer header received:");
         Print(StringSubstr(result,0,header_end));
        }
     }
//--- ferme la socket après son utilisation
   SocketClose(socket);
   /*
   résultat :
   Serverwww.google.com
   Port443
   TLS certificate:
      Owner: /CN=www.google.com
      Issuer: /C=US/O=Google Trust Services/CN=WR2
      Number0d:43:b1:4a:bb:9c:15:96:10:e1:3d:55:23:9f:25:4e
      Print89167618e5017f813aff981c88ce422dc1016bdf
      Expiration2024.12.30 08:26:35
 
   Request sentStarting page loading...
   HTTPRecvTLSDocument received within 27 attempts
   25185 bytes received
 
   HTTP answer header received:
   HTTP/1.1 200 OK
   DateFri25 Oct 2024 17:12:42 GMT
   Expires: -1
   Cache-Controlprivatemax-age=0
   Content-Typetext/htmlcharset=ISO-8859-1
   Content-Security-Policy-Report-Onlyobject-src 'none';base-uri 'self';script-src 'nonce-CUL2rdUOeAN7xIV6v0WUuQ' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inlinehttpshttp:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
   Accept-CHSec-CH-Prefers-Color-Scheme
   P3PCP="This is not a P3P policy! See g.co/p3phelp for more info."
   Servergws
   X-XSS-Protection0
   X-Frame-OptionsSAMEORIGIN
   Set-CookieAEC=AVYB7coyYMCdweTDTaWeGYzmRnxzKGqsOEosH_VkbCn8xhWkFz6v0kxQFwexpires=Wed23-Apr-2025 17:12:42 GMTpath=/; domain=.google.comSecureHttpOnlySameSite=lax
   Set-CookieNID=518=J02X02Ff4v_9sMcNoUz-1SolmuG08E26Gs438ik0J_SOJUMy7of-P-qup-LaNSWVXUL8OjhOXpGIGuJQGIoEPBnzqDKCH-46_FN4J2foHeWTlGG8bVVvQ44AHWLg1OXjrGp3CUBexYdczLWNy3LxEcb7eh6mxSvFzOelPC6-vpXkaumLQ80x9gF_RpLcAYfN4ehTexpires=Sat26-Apr-2025 17:12:42 GMTpath=/; domain=.google.comHttpOnly
   Alt-Svch3=":443"ma=2592000,h3-29=":443"ma=2592000
   Accept-Rangesnone
   VaryAccept-Encoding
   Transfer-Encodingchunked
   */
  }
//+------------------------------------------------------------------+
//| Envoie une requête HTTP via une connexion sécurisée              |
//+------------------------------------------------------------------+
bool HTTPSendTLS(int socket,const string request)
  {
//--- convertit la chaîne en un tableau de caractères, ignore le zéro de fin
   char req[];
   int  len=StringToCharArray(request,req,0,WHOLE_ARRAY,CP_UTF8)-1;
 
   if(len<0)
      return false;
 
   return(SocketTlsSend(socket,req,len)==len);
  }
//+------------------------------------------------------------------+
//| Récupère une page web page via une connexion sécurisée           |
//+------------------------------------------------------------------+
bool HTTPRecvTLS(int socket,uchar &response[],const uint timeout_ms)
  {
//--- lit les données disponibles à partir d'une connexion TLS sécurisée avant l'expiration du délai d'attente
   ulong timeout_check=GetTickCount64()+timeout_ms;
   uchar block[1024];   // buffer for block data reading from socket
   uint  attempt=0;     // requested number of data blocks
   int   err    =0;     // error code
 
   ResetLastError();
 
   do
     {
      //--- lecture par blocs, maximum 1024 octets
      int len=SocketTlsReadAvailable(socket,block,1024);
 
      if(len>0)
        {
         attempt++;
         //--- fusionne les blocs de données obtenus
         ArrayCopy(response,block,response.Size());
         //--- analyse les données obtenues, définit l'en-tête, le corps de la page, la fin ou l'erreur de chargement, etc.
         //...
         //...
         //...
         timeout_check=GetTickCount64()+timeout_ms;
        }
      else
         Sleep(10);
 
      err=GetLastError();
     }
   while(!IsStopped() && GetTickCount()<timeout_check && !err);
//--- y a-t-il eu des erreurs lors de la lecture ?
   if(err)
     {
      Print("Error ",err);
      return(false);
     }
 
   PrintFormat("%s: Document received within %d attempts",__FUNCTION__,attempt);
   return(true);
  }

Voir également

SocketTimeouts, MathSwap