- Envío de notificaciones push
- Envío de notificaciones por correo electrónico
- Envío de archivos a un servidor FTP
- Intercambio de datos con un servidor web a través de HTTP/HTTPS
- Establecer y romper una conexión de socket de red
- Comprobar el estado del socket
- Establecer tiempos de espera de envío y recepción de datos para sockets
- Leer y escribir datos a través de una conexión de socket insegura
- Preparar una conexión de socket segura
- Leer y escribir datos a través de una conexión de socket segura
Establecer y romper una conexión de socket de red
En las secciones anteriores nos hemos familiarizado con las funciones de red de alto nivel de MQL5: cada una de ellas proporciona soporte para un protocolo de aplicación específico. Por ejemplo, SMTP se utiliza para enviar correos electrónicos (SendMail), FTP para transferir archivos (SendFTP) y HTTP permite recibir documentos web (WebRequest). Todas las normas mencionadas se basan en una capa inferior, la de transporte TCP (Transmission Control Protocol). No es el último de la jerarquía, ya que también los hay inferiores, pero no los discutiremos aquí.
La implementación estándar de protocolos de aplicación esconde muchos matices técnicos en su interior y elimina la necesidad de que el programador siga rutinariamente las especificaciones durante horas. Sin embargo, carece de flexibilidad y no tiene en cuenta las funciones avanzadas que incrustadas en los estándares. Por lo tanto, a veces es necesario programar la comunicación de red a nivel TCP, es decir, a nivel de socket.
Un socket puede considerarse análogo a un archivo en un disco: un socket también se describe mediante un descriptor entero por el que se pueden leer o escribir datos, pero esto ocurre en una infraestructura de red distribuida. A diferencia de los archivos, el número de sockets en un ordenador es limitado, por lo que el descriptor de socket debe solicitarse previamente al sistema antes de asociarlo a un recurso de red (dirección, URL). Digamos también antes de nada que el acceso a la información a través de un socket es streaming, es decir, que es imposible «rebobinar» un determinado «puntero» hasta el principio, como en un archivo.
Los hilos de escritura y lectura no se cruzan, pero pueden afectar a futuros datos de lectura o escritura, ya que la información transmitida suele ser interpretada por los servidores y programas cliente como comandos de control. Los estándares de los protocolos definen si un flujo contiene comandos o datos.
La función SocketCreate permite la creación de un descriptor de socket «vacío» en MQL5.
int SocketCreate(uint flags = 0)
Su único parámetro se reserva para el futuro con el fin de especificar el patrón de bits de las banderas que determinan el modo del socket, pero por el momento sólo se admite una bandera «stub»: SOCKET_DEFAULT corresponde al modo actual y puede omitirse. A nivel de sistema, esto equivale a un socket en modo de bloqueo (esto puede interesar a los programadores de redes).
Si tiene éxito, la función devuelve el manejador del socket. En caso contrario, devuelve INVALID_HANDLE.
Se puede crear un máximo de 128 sockets desde un programa MQL. Cuando se supera el límite, se registra el error 5271 (ERR_NETSOCKET_TOO_MANY_OPENED) en _LastError.
Una vez abierto el socket, debe asociarse a una dirección de red.
bool SocketConnect(int socket, const string server, uint port, uint timeout)
La función SocketConnect establece una conexión de socket con el servidor en la dirección y el puerto especificados (por ejemplo, los servidores web suelen funcionar en los puertos 80 o 443 para HTTP y HTTPS, respectivamente, y SMTP en el puerto 25). La dirección puede ser un nombre de dominio o una dirección IP.
El parámetro timeout permite establecer un tiempo de espera en milisegundos para esperar una respuesta del servidor.
La función devuelve una señal de conexión correcta (true) o de error (false). El código de error se escribe en _LastError, por ejemplo, 5272 (ERR_NETSOCKET_CANNOT_CONNECT).
Tenga en cuenta que la dirección de conexión debe añadirse a la lista de direcciones permitidas en la configuración del terminal (cuadro de diálogo Service -> Settings -> Advisors).
Cuando haya terminado de trabajar con la red, debe liberar el socket con SocketClose.
bool SocketClose(const int socket)
La función SocketClose cierra el socket por su asa, abierta anteriormente mediante la función SocketCreate. Si el socket estaba previamente conectado a través de SocketConnect, la conexión se romperá.
La función también devuelve un indicador de éxito (true) o de error (false). En particular, cuando se pasa un manejador no válido a _LastError, se registra el error 5270 (ERR_NETSOCKET_INVALIDHANDLE).
Recordemos que todas las funciones de esta sección y de las siguientes están prohibidas en los indicadores: allí, un intento de trabajar con sockets dará como resultado el error 4014 (ERR_FUNCTION_NOT_ALLOWED, «No se permite llamar a la función del sistema»).
Consideremos un ejemplo introductorio, el script SocketConnect.mq5. En los parámetros de entrada puede especificar la dirección y el puerto del servidor. Se supone que debemos empezar las pruebas con servidores web normales como mql5.com.
input string Server = "www.mql5.com";
|
En la función OnStart simplemente creamos un socket y lo vinculamos a un recurso de red.
void OnStart()
|
Si todos los ajustes del terminal son correctos y está conectado a Internet, obtendremos el siguiente «informe».
Server=www.mql5.com / ok
|