第二十一章 网络功能(函数)
MQL 5程序可以与远程服务器交换数据,还可以通过FTP发送推送通知、电子邮件和数据。
• Socket 开头的函数组允许通过系统套接字与远程主机建立TCP连接(包括安全的TLS)。操作原理很简单:创建一个套接字,连接到 服务器并开始读取和写入数据。 • WebRequest函数设计用于处理Web资源,并允许轻松发送HTTP请求(包括GET和POST). • SendFTP、Sendmail和SendNotification是发送文件、电子邮件和移动通知的更简单的功能。
为了最终用户安全,允许的IP地址列表在客户端实现.该列表包含允许通过套接字 和WebReq连接到的MQL 5程序的IP地址。 最重要的功能。例如,如果程序需要连接到 https://www.someserver.com
,此地址应由列表中的终端用户显式指示。不能以编程方式添加地址.
将地址添加到列表中
向MQL 5程序添加显式消息,通知用户需要附加配置。您可以通过#property description, Alert 或 Print.来做到这一点。
函数 | 功能 |
---|---|
SocketCreate | 创建带有指定标志的连接套接字并返回其句柄 |
SocketClose | 关闭连接 |
SocketConnect | 使用超时控件连接到服务器 |
SocketIsReadable | 获取可以从套接字读取的字节数。 |
SocketIsWritable | 检查当前是否可以将数据写入套接字。 |
SocketTimeouts | 为套接字系统对象设置接收和发送数据的超时 |
SocketRead | 从套接字读取数据 |
SocketSend | 将数据写入套接字 |
SocketTlsHandshake | 通过TLS握手协议启动到指定主机的安全TLS(SSL)连接。 |
SocketTlsCertificate | 获取用于保护网络连接的证书上的数据。 |
SocketTlsRead | 从安全的TLS连接读取数据 |
SocketTlsReadAvailable | 从安全的TLS连接读取所有可用数据。 |
SocketTlsSend | 通过安全的TLS连接发送数据 |
WebRequest | 发送 HTTP 请求到指定服务器 |
SendFTP | 在"Publisher" 标签窗口中设置发送文件地址 |
SendMail | 在"Mailbox"标签窗口中发送邮件到指定地址 |
SendNotification | 向在“通知”标签指定MetaQuotes ID的移动程序端发送推送通知 |
# 21.1 SocketCreate
创建具有指定标志的套接字并返回其句柄。
int SocketCreate(
uint flags // flags
);
2
3
参数
flags
[in] 定义使用套接字的模式的标志组合。目前,只支持一个标志-Socket_DEFAULT。
返回值
如果套接字创建成功,返回其句柄,否则无效句柄。
注意
若要从未使用的套接字中释放计算机内存,请调用套接字。
您可以从一个MQL 5程序最多创建128个套接字。如果超出限制,则将错误5271(ERR_NETSOCKET_OUL_ONY_OPEN)写入 _LastError。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标中调用,GetLastError()返回错误4014-“函数禁止调用”。
例
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount() < timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 21.2 SocketClose
关闭连接。
bool SocketClose(
const int socket // socket handle
);
2
3
参数
socket
[in] 要关闭的插座的手柄。句柄由SocketCreate函数返回。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
返回值
如果成功返回true,否则返回false。
注意
如果以前为套接字创建了通过SocketConnect的连接,则将停止连接。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
例:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 21.3 SocketConnect
使用超时控件连接到服务器.
bool SocketConnect(
int socket, // socket
const string server, // connection address
uint port, // connection port
uint timeout_receive_ms // connection timeout
);
2
3
4
5
6
参数
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
server
[in] 要连接到的服务器的域名或其IP地址。
port
[in] 连接的端口号
timeout_receive_ms
[in] 连接超时(毫秒)。如果在此时间间隔内未建立连接,则停止尝试。
返回值
如果连接成功,则返回true,否则返回false。
注意
连接地址应该添加到客户端允许的连接地址列表中(Tools\Options\ExpertAdvisors)。
如果连接失败,则将错误5272(ERR_NETSOCKET_NOT_CONNECT)写入_LastError。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
例:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 21.4 SocketIsConnected
检查套接字当前是否已连接。
bool SocketIsConnected(
const int socket // socket handle
);
2
3
参数
socket
[in] SocketCreate()函数返回的套接字句柄。当将不正确的句柄传递给_LastError时,将激活错误5270(ERR_NETSOCKET_INVALIDHANDLE)。
返回值
如果套接字已连接,则返回true,否则为false。
注意
函数允许检查当前套接字连接状态。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
参考
SocketConnect, SocketIsWritable, SocketCreate, SocketClose
# 21.5 SocketIsReadable
获取可以从套接字读取的字节数。
uint SocketIsReadable(
const int socket // socket handle
);
2
3
参数
socket
[in] SocketCreate函数返回的套接字句柄。当将不正确的句柄传递给_LastError时,将激活错误5270(ERR_NETSOCKET_INVALIDHANDLE)。
返回值
可计算的字节数。如果出现错误,则返回0。
注意
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
在调用SocketRead之前,请检查套接字是否具有读取数据的功能。否则,如果没有数据,SocketRead函数将在timeout_ms内等待数据,延迟程序执行。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
例:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# 21.6 SocketIsWritable
检查当前是否可以将数据写入套接字。
bool SocketIsWritable(
const int socket // socket handle
);
2
3
参数
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
返回值
如果可能写入,则返回true,否则为false。.
注意
此函数允许您检查是否可以立即将数据写入套接字。
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
# 21.7 SocketTimeouts
设置接收和发送套接字系统对象数据的超时。
bool SocketTimeouts(
int socket, // socket
uint timeout_send_ms, // data sending timeout
uint timeout_receive_ms // data obtaining timeout
);
2
3
4
5
参数
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
timeout_send_ms
[in] 发送超时的数据以毫秒为单位。
timeout_receive_ms
[in] 数据获取超时(以毫秒为单位)。
返回值
如果成功返回true,否则返回false。
注意
不要混淆系统对象超时和通过SocketRead读取数据时设置的超时。SocketTimeout为操作系统中的套接字对象设置一次超时。这些超时将被应用 d通过这个套接字读取和发送数据的所有函数。在SocketRead中,为特定的数据读取操作设置超时。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
# 21.8 SocketRead
从套接字读取数据。
int SocketRead(
int socket, // socket
uchar& buffer[], // buffer for reading data from socket
uint buffer_maxlen, // number of bytes to read
uint timeout_ms // reading timeout
);
2
3
4
5
6
参数
socket
[in] SocketCreate函数返回的套接字句柄。当将不正确的句柄传递给_LastError时,将激活错误5270(ERR_NETSOCKET_INVALIDHANDLE)。
buffer
[out] 对数据读取的uchar类型数组的引用。动态数组大小随读取字节数的增加而增加。数组大小不能超过int_max(2147483647)。
buffer_maxlen
[in] 要读取到缓冲区[]数组的字节数。不适合数组的数据保留在套接字中。它们可以在下一个SocketRead电话中接收到。缓冲器_maxlen不能超过int_max(2147483647) .
timeout_ms
[in] 数据读取超时(毫秒)。如果在此时间内未获得数据,则停止尝试,函数返回-1。
返回值
如果成功,则返回读取字节数。如果出现错误,则返回-1。
注意
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
在数据读取错误的情况下,错误5273(Err_NETSOCKET_IO_Error)用_LastError编写。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
例:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 21.9 SocketSend
将数据写入套接字。
int SocketSend(
int socket, // socket
const uchar& buffer[], // data buffer
uint buffer_len // buffer size
);
2
3
4
5
返回值
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
buffer
[in] 引用带有要发送到套接字的数据的uchar类型数组。
buffer_len
[in] “缓冲区”数组大小。
返回值
如果成功,则返回写入套接字的字节数。如果出现错误,则返回-1。
注意
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
在数据写入错误的情况下,将错误5273(Err_NETSOCKET_IO_Error)写入_LastError。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
例:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
参见 SocketTimeouts, MathSwap, StringToCharArray
# 21.10 SocketTlsHandshake
通过TLS握手协议启动到指定主机的安全TLS(SSL)连接。在握手过程中,客户端和服务器在连接参数上达成一致:应用协议版本和数据加密。 关于方法。
bool SocketTlsHandshake(
int socket, // socket
const string host // host address
);
2
3
4
参数
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
host
[in] 建立安全连接的主机的地址。
返回值
如果成功返回true,否则返回false。
注意
在安全连接之前,程序应该使用SocketConnect与主机建立标准TCP连接。
如果安全连接失败,则将错误5274(ERR_NETSOCKET_HANDHAND_FILED)写入_LastError。
连接到端口443时不需要调用该函数。这是用于安全TLS(SSL)连接的标准TCP端口。 该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
# 21.11 SocketTlsCertificate
获取用于保护网络连接的证书上的数据。
int SocketTlsCertificate(
int socket, // socket
string& subject, // certificate owner
string& issuer, // certificate issuer
string& serial, // certificate serial number
string& thumbprint, // certificate print
datetime&& expiration // certificate expiration
);
2
3
4
5
6
7
8
参数
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
subject
[in] 证书所有者名称。对应于主题字段。
issuer
[in] 证书所有者名称。对应于Issuer字段。
serial
[in] 证书序列号。对应于SerialNumber字段。
thumbprint
[in] 证书打印。对应于来自整个证书文件的SHA-1散列(所有字段,包括颁发者签名)。
expiration
[in] 日期时间格式的证书过期日期。
返回值
如果成功返回true,否则返回false。 注意
只有在使用SocketTlsHand握手建立安全连接之后才能请求证书数据。
如果证书获取错误,则将错误5275(err_NETSOCKET_NO_证书)写入_LastError。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
# 21.12 SocketTlsRead
取消订阅。
int SocketTlsRead(
int socket, // socket
uchar& buffer[], // buffer for reading data from socket
uint buffer_maxlen // number of bytes to read
);
2
3
4
5
参数
socket
[in] SocketCreate函数返回的套接字句柄。当将不正确的句柄传递给_LastError时,将激活错误5270(ERR_NETSOCKET_INVALIDHANDLE)。
buffer
[out] 对数据读取的uchar类型数组的引用。动态数组大小随读取字节数的增加而增加。数组大小不能超过int_max(2147483647)。
buffer_maxlen
[in] 要读取到缓冲区[]数组的字节数。不适合数组的数据保留在套接字中。它们可以在下一个SocketTLSRead电话中接收到。缓冲区最大限度不能超过int_max(21474836) 47).
返回值
如果成功,则返回读取字节数。如果出现错误,则返回-1。
注意
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
函数将被执行,直到它接收到指定的数据量或达到超时为止(SocketTimeout)。
在数据读取错误的情况下,错误5273(Err_NETSOCKET_IO_Error)用_LastError编写。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
例:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work"
#property script_show_inputs
input string Address="www.mql5.com";
input int Port =80;
bool ExtTLS =false;
//+------------------------------------------------------------------+
//| Send command to the server |
//+------------------------------------------------------------------+
bool HTTPSend(int socket,string request)
{
char req[];
int len=StringToCharArray(request,req)-1;
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
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);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
参考 SocketTimeouts, MathSwap
# 21.13 SocketTlsReadAvailable
从安全的TLS连接读取所有可用数据。 ``` cpp` int SocketTlsReadAvailable( int socket, // socket uchar& buffer[], // buffer for reading data from socket const uint buffer_maxlen // number of bytes to read );
参数
socket
[in] SocketCreate函数返回的套接字句柄。当将不正确的句柄传递给_LastError时,将激活错误5270(ERR_NETSOCKET_INVALIDHANDLE)。
buffer
[out] 对数据读取的uchar类型数组的引用。动态数组大小随读取字节数的增加而增加。数组大小不能超过int_max(2147483647)。
buffer_maxlen
[in] 要读取到缓冲区[]数组的字节数。不适合数组的数据保留在套接字中。它们可以由下一个SocketTlsReadAvailable或SocketTlsRead调用接收。缓冲器最大角 t超过int_max(2147483647)。
返回值
如果成功,则返回读取字节数。如果出现错误,则返回-1。
注意
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
在数据读取错误的情况下,错误5273(Err_NETSOCKET_IO_Error)用_LastError编写。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
参考
SocketTimeouts, MathSwap
## 21.14 SocketTlsSend
通过安全的TLS连接发送数据。
``` cpp
int SocketTlsSend(
int socket, // socket
const uchar& buffer[], // data buffer
uint buffer_len // buffer size
);
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
参数
socket
[in] SocketCreate函数返回的套接字句柄。当传递不正确的句柄时,错误5270(ERR_NETSOCKET_INVALIDHANDLE)被写入_LastError。
buffer
[in] 引用要发送数据的uchar类型数组。
buffer_len
[in] “缓冲区”数组大小。
返回值
如果成功,则返回写入套接字的字节数。如果出现错误,则返回-1。
注意
如果在执行函数时系统套接字上发生错误,则将停止通过SocketConnect建立的连接。
在数据写入错误的情况下,将错误5273(Err_NETSOCKET_IO_Error)写入_LastError。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
参考
SocketTimeouts, MathSwap, StringToCharArray
# 21.15 WebRequest
发送 HTTP 请求到指定服务器。 该函数有两个版本:
- 发送简单请求 使用内容-类型标题的"key=value"类型:application/x-www-form-urlencoded
int WebRequest(
const string method, // HTTP 请求方式
const string url, // url 地址
const string cookie, // cookie
const string referer, // 参照页
int timeout, // 超时
const char &data[], // HTTP请求信息数组
int data_size, // data[] 数组大小
char &result[], // 服务器响应数据数组
string &result_headers // 服务器响应标头
);
2
3
4
5
6
7
8
9
10
11
- 发送任何类型的请求 为了各种网络服务的更灵活互动指定自定义的标题设置。
int WebRequest(
const string method, // HTTP 方法
const string url, // URL
const string headers, // 标题
int timeout, // 超时
const char &data[], // HTTP 信息主体的数组
char &result[], // 包含服务器反应数据的数组
string &result_headers // 服务器响应标题
);
2
3
4
5
6
7
8
9
参数
method
[in] HTTP 请求方法。
url
[in] URL 地址。
headers
[in] "key: value"类型的请求标题,以分行符 "\r\n"分隔。
cookie
[in] Cookie。
referer
[in] HTTP 请求标头的推荐页字段
timeout
[in] 超时时间以毫秒为单位。
data[]
[in] HTTP 请求信息数组。
data_size
[in] data[] 数组大小。
result[]
[out] 服务器响应数据数组。
result_headers
[out] 服务器响应标头。
返回值
服务器响应的HTTP 状态码,或错误情况下的 -1 。
注意
若要能够使用WebRequest 函数,您必须在“选项”窗口“EA交易”标签的允许URLs列表中添加一个URL。
WebRequest 是一个同步函数。这意味着它会阻止程序执行并且等候请求服务器的响应。当收到发送请求的响应时,延迟至关重要,这就是禁止从指标调用该函数的原因,因为指标按照交易品种组指标的自己的执行线程操作。在一个图表上执行指标延迟可能导致该交易品种的所有图表停止更新。
该函数只能从EA和脚本中调用,因为它们在自己的执行线程中运行。如果从指标调用,GetLastError()返回错误4014-“函数禁止调用“。
WebRequest() 函数不能在 策略测试中执行。
例如:
# 21.16 SendFTP
按”选项”设置窗口中“FTP”标签中指定的地址发送一个文件
bool SendFTP(
string filename, // 通过ftp发送的文件
string ftp_path=NULL // ftp服务器上传的文件
);
2
3
4
参数
filename
[in] 发送文件名称
ftp_path=NULL
[in] FTP目录,如果目录未标明,直接使用在设置中的描述
返回值
错误返回是“false”。
注意
发送文件应该保存在 terminal_directory\MQL5\files 或子文件夹中保存,如果在设置中未标明FTP地址或者访问密码,无法发送。
SendFTP() 函数在策略测试中不工作。
# 21.17 SendMail
按”选项”设置窗口中“电邮”标签中指定的地址发送一个邮件
bool SendMail(
string subject, // 表头
string some_text // email 文本
);
2
3
4
参数
subject
[in] 邮件标题
some_text
[in] 邮件主题
返回值
如果邮件发送到派送队列则返回true,否则返回false
注意
在设置中发送邮件功能可能被禁止,也可能邮件地址未标明,查看错误信息请调用 GetLastError()
SendMail() 函数在策略测试中不工作。
# 21.18 SendNotification
按”选项”设置窗口中“通知”标签中指定的 MetaQuotes ID 推送一个短消息
bool SendNotification(
string text // 通知文本
);
2
3
参数
text
[in] 通知文本。信息长度不应该超过 255 字符。
返回值
如果通知从程序端成功发送,则返回true;如果失败则返回false。推送通知失败后检查时,GetLastError () 可能返回其中以下一种错误: • 4515 —— ERR_NOTIFICATION_SEND_FAILED, • 4516 —— ERR_NOTIFICATION_WRONG_PARAMETER, • 4517 —— ERR_NOTIFICATION_WRONG_SETTINGS, • 4518 —— ERR_NOTIFICATION_TOO_FREQUENT.
注意
为SendNotification()函数设置了严格的使用限制:每秒钟调用不能超过2次,每分钟调用不能超过10次。动态监控使用频率。如果违反这些限制,函数将被禁用。
SendNotification() 函数在策略测试中不工作。