SocketTlsReadAvailable

Leggi tutti i dati disponibili dalla connessione TLS protetta.

int  SocketTlsReadAvailable(
   int           socket,               // socket
   uchar&        buffer[],             // buffer per la lettura dei dati dal socket
   const uint    buffer_maxlen         // numero di byte da leggere
   );

Parametri

socket

[in] Handle del socket restituito dalla funzione SocketCreate. Quando viene passato un handle errato _LastError, si attiva l'errore 5270 (ERR_NETSOCKET_INVALIDHANDLE).

buffer

[out] Riferimento all'array di tipo uchar in cui vengono letti i dati. La dimensione dinamica dell'array è aumentata dal numero di byte letti. La dimensione dell'array non può superare INT_MAX (2147483647).

buffer_maxlen

[in] Numero di byte da leggere sull'array del buffer[]. I dati non adattati all'array rimangono nel socket. Possono essere ricevuti dalla prossima chiamata SocketTlsReadAvailable oSocketTlsRead. buffer_maxlen cannot exceed INT_MAX (2147483647).

Valore di Ritorno

Se ha successo, restituisce il numero di byte letti. In caso di errore, viene restituito -1.

Nota

Se si verifica un errore su un socket di sistema durante l'esecuzione della funzione, la connessione stabilita tramite SocketConnect viene interrotta.

In caso di errore di lettura dei dati, l'errore 5273 (ERR_NETSOCKET_IO_ERROR) viene scritto in _LastError.

La funzione può essere chiamata solo da Expert Advisors e scripts, poiché vengono eseguiti nei relativi thread di esecuzione. Se si chiama da un indicatore, GetLastError() restituisce l'errore 4014 - "Function is not allowed for call (la funzione non è consentita per la chiamata)".

Esempio:

//+------------------------------------------------------------------+
//|                                       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
//+------------------------------------------------------------------+
//| Input dello script                                               |
//+------------------------------------------------------------------+
input string InpMethod ="GET";            // Metodo (HEAD,GET)
input string InpServer ="www.google.com"// Server
input uint   InpPort   =443;              // Porta
input uint   InpTimeout=5000;             // Timeout
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(void)
  {
   Print("Server: ",InpServer);
   Print("Port: ",InpPort);
//--- creare un socket e ottenere il suo handle (gestore)
   const int socket=SocketCreate();
 
   if(socket==INVALID_HANDLE)
     {
      Print("SocketCreate() failed. Error ",GetLastError());
      return;
     }
//--- impostare i tempi di attesa per la ricezione e l'invio dei dati per un oggetto del sistema socket
   if(!SocketTimeouts(socket,InpTimeout,InpTimeout))
     {
      PrintFormat("SocketTimeouts(%u, %u) failed. Error %d",InpTimeout,InpTimeout,GetLastError());
      SocketClose(socket);
      return;
     }
//--- connettersi al Server tramite la Porta
   if(!SocketConnect(socket,InpServer,InpPort,InpTimeout))
     {
      PrintFormat("SocketConnect('%s', %u, %u) failed. Error %d",InpServer,InpPort,InpTimeout,GetLastError());
      SocketClose(socket);
      return;
     }
//--- ottenere i dati sul certificato utilizzato per proteggere la connessione di rete
   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
     {
 //--- il server non fornisce un certificato - segnala una connessione non protetta e lascia
      Print("The connection is not secured by a certificate");
      SocketClose(socket);
      return;
     }
//--- inviare una richiesta al server
   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))
     {
 //--- richiesta inviata - ottenere la risposta
      Print("\nRequest sent. Starting page loading...");
 uchar response[]; // tutti i dati ricevuti (header e body del documento)
 
      if(!HTTPRecvTLS(socket,response,InpTimeout))
        {
         Print("There were errors while reading the page");
         SocketClose(socket);
         return;
        }
 //--- indicare il numero di byte di dati ricevuti
      PrintFormat("%u bytes received",response.Size());
 //--- visualizzare solo l'header della pagina ottenuta
      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));
        }
     }
//--- chiudere il socket dopo l'uso
   SocketClose(socket);
   /*
   risultato:
   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
   */
  }
//+-----------------------------------------------------------------------------------+
//| Inviare una richiesta HTTP su una connessione sicura                              |
//+-----------------------------------------------------------------------------------+
bool HTTPSendTLS(int socket,const string request)
  {
//--- convertire la stringa in un array di caratteri, scartare lo zero finale
   char req[];
   int  len=StringToCharArray(request,req,0,WHOLE_ARRAY,CP_UTF8)-1;
 
   if(len<0)
      return false;
 
   return(SocketTlsSend(socket,req,len)==len);
  }
//+-----------------------------------------------------------------------------------+
//| Ottenere una pagina web tramite una connessione sicura                            |
//+-----------------------------------------------------------------------------------+
bool HTTPRecvTLS(int socket,uchar &response[],const uint timeout_ms)
  {
//--- leggere i dati disponibili dalla connessione TLS sicura prima che il timeout scada
   ulong timeout_check=GetTickCount64()+timeout_ms;
   uchar block[1024];   // buffer per la lettura dei dati a blocchi dal socket
   uint  attempt=0;     // numero richiesto di blocchi di dati
   int   err    =0;     // codice errore
 
   ResetLastError();
 
   do
     {
      //--- lettura in blocchi, massimo 1024 byte
      int len=SocketTlsReadAvailable(socket,block,1024);
 
      if(len>0)
        {
         attempt++;
 //--- unire i blocchi di dati ottenuti
         ArrayCopy(response,block,response.Size());
 //--- analizzare i dati ottenuti, definire l'intestazione, il corpo della pagina, la fine o l'errore di caricamento, ecc.
         //...
         //...
         //...
         timeout_check=GetTickCount64()+timeout_ms;
        }
      else
         Sleep(10);
 
      err=GetLastError();
     }
   while(!IsStopped() && GetTickCount()<timeout_check && !err);
//--- c'erano degli errori durante la lettura?
   if(err)
     {
      Print("Error ",err);
      return(false);
     }
 
   PrintFormat("%s: Document received within %d attempts",__FUNCTION__,attempt);
   return(true);
  }

Guarda anche

SocketTimeouts, MathSwap