Для 64-разрядного терминала определяем такой макрос:
#define _WIN64 // Только для 64-разрядного терминала!
Дальше выкладываю Ваш исправленный пример.
#ifdef _WIN64 #define PVOID ulong #else #define PVOID uint #endif #define DWORD_PTR PVOID #define SOCKET PVOID #define BYTE uchar #define WORD ushort #define DWORD uint #define UINT uint #define AF_INET 2 // internetwork: UDP, TCP, etc. #define SOCK_STREAM 1 // stream socket #define IPPROTO_TCP 6 // tcp #define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) #define WSADESCRIPTION_LEN 256 #define WSASYS_STATUS_LEN 128 #define RCVBUFFSIZE 1024 struct WSADATA { WORD wVersion; WORD wHighVersion; #ifdef _WIN64 ushort iMaxSockets; ushort iMaxUdpDg; PVOID lpVendorInfo; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; #else char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; ushort iMaxSockets; ushort iMaxUdpDg; PVOID lpVendorInfo; #endif }; #define INVALID_SOCKET (SOCKET)(~0) #define IN_ADDR uint #define INADDR_ANY (uint)0x00000000 struct SOCKADDR_IN { short sin_family; ushort sin_port; IN_ADDR sin_addr; char sin_zero[8]; }; #import "Ws2_32.dll" int WSAStartup( ushort wVersionRequested, WSADATA& lpWSAData ); int WSACleanup(); int WSAGetLastError(); SOCKET socket( int af, int type, int protocol ); int shutdown( SOCKET socket, int how ); int closesocket( SOCKET socket ); int bind( SOCKET socket, SOCKADDR_IN& lpSockAddr, int size ); int listen( SOCKET socket, int backlog ); int accept( SOCKET socket, PVOID a=0, PVOID b=0 ); int recv( SOCKET socket, char& lpBuffer[], int bufferLen, int flags ); ushort ntohs( ushort number ); ushort htons( ushort number ); #import //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { // dll initialization WORD wVersionRequested = MAKEWORD( 2, 2 ); WSADATA wsaData; int errno = WSAStartup( wVersionRequested, wsaData ); if( errno != 0 ){ ErrorLog( "WSAStartup", errno ); return; } // make listen socket SOCKET serverSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if( serverSocket == INVALID_SOCKET ) { ErrorLog( "socket", WSAGetLastError() ); WSACleanup(); return; } // bind to port SOCKADDR_IN service; service.sin_family = AF_INET; ushort portNumber = 13313; Print( "Bind to port ", portNumber ); service.sin_port = htons( portNumber ); service.sin_addr = INADDR_ANY; errno = bind( serverSocket, service, sizeof(service) ); if( errno != 0 ) { ErrorLog( "bind", WSAGetLastError() ); closesocket( serverSocket ); WSACleanup(); return; } errno = listen( serverSocket, 1 ); if( errno != 0 ) { ErrorLog( "listen", WSAGetLastError() ); closesocket( serverSocket ); WSACleanup(); return; } // wait for incoming connection SOCKET clientSocket = accept( serverSocket, 0, 0 ); if( clientSocket == INVALID_SOCKET ) { ErrorLog( "accept", WSAGetLastError() ); closesocket( serverSocket ); WSACleanup(); return; } // wait for incoming data char rcvBuffer[RCVBUFFSIZE]; int bytesCnt = recv( clientSocket, rcvBuffer, RCVBUFFSIZE, 0 ); if( bytesCnt > 0 ) { Print( "Received ", bytesCnt, " bytes" ); } else if( bytesCnt == 0 ) { Print( "Connection closed" ); } else { ErrorLog( "recv", WSAGetLastError() ); } // dll clenup closesocket(clientSocket); closesocket(serverSocket); WSACleanup(); } //+------------------------------------------------------------------+ void ErrorLog( string functionName, int errno ) { Print( "\"", functionName, "()\" has failure with error code: ", errno, " see winsock erorr codes" ); } //+------------------------------------------------------------------+
пробую реализовать отправку пакета из индикатора по протоколу UDP
свиду уходит пакет но до адресата на C# данный пакет ее приходит
если внутри C# пробовать отправить пакет то проблем нет
вот код индикатора
//+------------------------------------------------------------------+ //| SendProfit.mq4 | //| Copyright 2015, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #property indicator_chart_window #ifdef _WIN64 #define PVOID ulong #else #define PVOID uint #endif #define DWORD_PTR PVOID #define SOCKET PVOID #define BYTE uchar #define WORD ushort #define DWORD uint #define UINT uint #define AF_INET 2 // internetwork: UDP, TCP, etc. #define SOCK_STREAM 1 // stream socket #define SOCK_DGRAM 2 // datagram socket #define SOCKET_ERROR (-1) #define IPPROTO_UDP 17 // user datagram protocol #define IPPROTO_TCP 6 // tcp #define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) #define WSADESCRIPTION_LEN 256 #define WSASYS_STATUS_LEN 128 #define RCVBUFFSIZE 1024 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct WSADATA { WORD wVersion; WORD wHighVersion; #ifdef _WIN64 ushort iMaxSockets; ushort iMaxUdpDg; PVOID lpVendorInfo; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; #else char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; ushort iMaxSockets; ushort iMaxUdpDg; PVOID lpVendorInfo; #endif }; #define INVALID_SOCKET (SOCKET)(~0) #define IN_ADDR uint #define INADDR_ANY (uint)0x00000000 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct SOCKADDR_IN { short sin_family; ushort sin_port; IN_ADDR sin_addr; char sin_zero[8]; }; #import "Ws2_32.dll" int WSAStartup(ushort wVersionRequested,WSADATA &lpWSAData); int WSACleanup(); int WSAGetLastError(); SOCKET socket(int af,int type,int protocol); int shutdown(SOCKET socket,int how); int closesocket(SOCKET socket); int bind(SOCKET socket,SOCKADDR_IN &lpSockAddr,int size); int listen(SOCKET socket,int backlog); int accept(SOCKET socket,PVOID a=0,PVOID b=0); int recv(SOCKET socket,char &lpBuffer[],int bufferLen,int flags); int send(SOCKET s,char &buf[],int len,int flags); int sendto(SOCKET s,char &buf[],int len,int flags,SOCKADDR_IN &to,int tolen); ushort ntohs(ushort number); ushort htons(ushort number); uint inet_addr(char &cp[]); #import SOCKET serverSocket;//sSocketSender; SOCKADDR_IN service; SOCKADDR_IN RemoteIPPort; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { // dll initialization WORD wVersionRequested=MAKEWORD(2,2); WSADATA wsaData; int errno= WSAStartup(wVersionRequested,wsaData); if(errno!=0) { ErrorLog("WSAStartup",errno); return(INIT_FAILED); } // make listen socket //serverSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); serverSocket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if(serverSocket==INVALID_SOCKET) { ErrorLog("socket",WSAGetLastError()); WSACleanup(); return(INIT_FAILED); } // bind to port service.sin_family= AF_INET; ushort portNumber = 3795; service.sin_port=htons(portNumber); //service.sin_addr = INADDR_ANY; char charAdd[]; StringToCharArray("127.0.0.1",charAdd,0,-1,CP_ACP); service.sin_addr=inet_addr(charAdd); RemoteIPPort.sin_family=AF_INET; RemoteIPPort.sin_port=htons(3795); StringToCharArray("192.168.1.10",charAdd,0,-1,CP_ACP); RemoteIPPort.sin_addr=inet_addr(charAdd); errno=bind(serverSocket,service,sizeof(service)); if(errno!=0) { ErrorLog("bind",WSAGetLastError()); closesocket(serverSocket); WSACleanup(); return(INIT_FAILED); } else {Print("Bind to port ",portNumber);} return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ { //closesocket(clientSocket); closesocket(serverSocket); WSACleanup(); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- char str[]; string sToSend="12257:1257.5"; StringToCharArray(sToSend,// строка-источник str,// массив 0, // начальная позиция в массиве -1, // количество символов CP_ACP // кодовая страница ); DWORD res=sendto(serverSocket,str,StringLen(sToSend),0,RemoteIPPort,sizeof(RemoteIPPort));//==SOCKET_ERROR Comment(res); return(rates_total); } //+------------------------------------------------------------------+ void ErrorLog(string functionName,int errno) { Print("\"",functionName,"()\" has failure with error code: ",errno," see winsock erorr codes"); } //+------------------------------------------------------------------+
В комментарий пишет 12 (тоесть ошибки отправки нет)
Подскажите что не так.
///
Вопрос снят сам разобрался
пробую реализовать отправку пакета из индикатора по протоколу UDP
свиду уходит пакет но до адресата на C# данный пакет ее приходит
если внутри C# пробовать отправить пакет то проблем нет
вот код индикатора
В комментарий пишет 12 (тоесть ошибки отправки нет)
Подскажите что не так.
///
Вопрос снят сам разобрался
Код индикатора отправляющего эквити из терминала далее по UDP (большая часть индикатора не моя)
//+------------------------------------------------------------------+ //| SendProfit.mq4 | //| Copyright 2015, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.05" #property strict #property indicator_chart_window extern string remoteIP="0.0.0.0"; // Удаленный IP для сбора эквити extern int remotePort=3093; // Удаленный порт для сбора эквити (как portForGetEquaty) #ifdef _WIN64 #define PVOID ulong #else #define PVOID uint #endif #define DWORD_PTR PVOID #define SOCKET PVOID #define BYTE uchar #define WORD ushort #define DWORD uint #define UINT uint #define AF_INET 2 // internetwork: UDP, TCP, etc. #define SOCK_STREAM 1 // stream socket #define SOCK_DGRAM 2 // datagram socket #define SOCKET_ERROR (-1) #define IPPROTO_UDP 17 // user datagram protocol #define IPPROTO_TCP 6 // tcp #define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) #define WSADESCRIPTION_LEN 256 #define WSASYS_STATUS_LEN 128 #define RCVBUFFSIZE 1024 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct WSADATA { WORD wVersion; WORD wHighVersion; #ifdef _WIN64 ushort iMaxSockets; ushort iMaxUdpDg; PVOID lpVendorInfo; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; #else char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; ushort iMaxSockets; ushort iMaxUdpDg; PVOID lpVendorInfo; #endif }; #define INVALID_SOCKET (SOCKET)(~0) #define IN_ADDR uint #define INADDR_ANY (uint)0x00000000 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct SOCKADDR_IN { short sin_family; ushort sin_port; IN_ADDR sin_addr; char sin_zero[8]; }; #import "Ws2_32.dll" int WSAStartup(ushort wVersionRequested,WSADATA &lpWSAData); int WSACleanup(); int WSAGetLastError(); SOCKET socket(int af,int type,int protocol); int shutdown(SOCKET socket,int how); int closesocket(SOCKET socket); int bind(SOCKET socket,SOCKADDR_IN &lpSockAddr,int size); int listen(SOCKET socket,int backlog); int accept(SOCKET socket,PVOID a=0,PVOID b=0); int recv(SOCKET socket,char &lpBuffer[],int bufferLen,int flags); int send(SOCKET s,char &buf[],int len,int flags); int sendto(SOCKET s,char &buf[],int len,int flags,SOCKADDR_IN &to,int tolen); ushort ntohs(ushort number); ushort htons(ushort number); uint inet_addr(char &cp[]); #import SOCKET serverSocket;//sSocketSender; SOCKADDR_IN service; SOCKADDR_IN RemoteIPPort; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { // dll initialization WORD wVersionRequested=MAKEWORD(2,2); WSADATA wsaData; int errno= WSAStartup(wVersionRequested,wsaData); if(errno!=0) { ErrorLog("WSAStartup",errno); return(INIT_FAILED); } // make listen socket serverSocket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if(serverSocket==INVALID_SOCKET) { ErrorLog("socket",WSAGetLastError()); WSACleanup(); return(INIT_FAILED); } // bind to port service.sin_family=AF_INET; ushort portNumber=3000; // с какого порта отправляем service.sin_addr=INADDR_ANY; for(int i=0;i<100;i++) { // поиск свободного порта service.sin_port=htons(portNumber+i); errno=bind(serverSocket,service,sizeof(service)); if(errno!=0) { //ErrorLog("bind",WSAGetLastError()); //closesocket(serverSocket); //WSACleanup(); //return(INIT_FAILED); } else {Print("Bind to port ",portNumber+i);break;} } char charAdd[]; RemoteIPPort.sin_family=AF_INET; RemoteIPPort.sin_port=htons(remotePort); // на какой порт отправляем StringToCharArray(remoteIP,charAdd,0,-1,CP_ACP); RemoteIPPort.sin_addr=inet_addr(charAdd); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ { //closesocket(clientSocket); closesocket(serverSocket); WSACleanup(); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- char str[]; string sToSend=AccountInfoInteger(ACCOUNT_LOGIN)+":"+AccountProfit(); StringToCharArray(sToSend,// строка-источник str,// массив 0, // начальная позиция в массиве -1, // количество символов CP_ACP // кодовая страница ); DWORD res=sendto(serverSocket,str,StringLen(sToSend),0,RemoteIPPort,sizeof(RemoteIPPort));//==SOCKET_ERROR //Print(sToSend+" "+res); return(rates_total); } //+------------------------------------------------------------------+ void ErrorLog(string functionName,int errno) { Print("\"",functionName,"()\" has failure with error code: ",errno," see winsock erorr codes"); } //+------------------------------------------------------------------+
В C# (основа)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Net; using System.Net.Sockets; using System.Threading; using System.IO; using System.IO.MemoryMappedFiles; namespace mytest { public partial class Form1 : Form { public Thread tRecEquaty; public UdpClient receivingUdpClient; public int maxAccount = 0; // будет увеличиваться по мере поступления новых данных от счетов public profit[] allProfit = new profit[100]; //например, возьмем длину массива = 100 public IPEndPoint ThisIpEndPoint; private void Form1_Load(object sender, EventArgs e) { ThisIpEndPoint = new IPEndPoint(IPAddress.Any, 0); receivingUdpClient = new UdpClient(3093); tRecEquaty = new Thread(new ThreadStart(Receiver_GetEquaty)); tRecEquaty.Start(); } public void Receiver_GetEquaty() { try { while (true) { // Ожидание дейтаграммы byte[] receiveBytes = receivingUdpClient.Receive(ref ThisIpEndPoint); // Преобразуем и отображаем данные string returnData = Encoding.UTF8.GetString(receiveBytes); string[] str = returnData.Split(':'); int i = 0; for (i = 0; i < maxAccount; i++) { if (str[0].ToString() == allProfit[i].accID) { break; } } allProfit[i].accID = str[0].ToString(); allProfit[i].Equaty = Convert.ToDecimal(str[1]); if (i == maxAccount) { maxAccount++; } decimal allSumm = 0.0m; if (maxAccount > 0) { for (int i = 0; i < maxAccount; i++) { allSumm += allProfit[i].Equaty; } if (allSumm != 0.0m) { lProfit.Text = allSumm.ToString("#.#"); } else { lProfit.Text = "Profit"; } if (allSumm < 0.0m) { lProfit.ForeColor = Color.FromName("Red"); } if (allSumm > 0.0m) { lProfit.ForeColor = Color.FromName("DarkGreen"); } if (allSumm == 0.0m) { lProfit.ForeColor = Color.FromName("Orange"); } } } } catch (Exception ex) { //Console.WriteLine("Возникло исключение: " + ex.ToString() + "\n " + ex.Message); } } }
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
День добрый.
Проблема с вызовами функций из системных dll. Задача -- написать простенький сервер TCP на MQL5, к-ый висит на определенном порту и просто принимает сообщения.
Импортировал из ws2_32.dll функции WSAStartup(), WSAClenup(), socket(), bind(), accept(), listen(), recv(). Все работает ровно до того, пока не попытаешься остановить сервер. После попытки остановит сервер и корректно завершить работу скрипта, терминал просто вылетает.
Методом научного тыка вышел на функцию recv().
в прикрепленном файле есть строчка (171):
если ее привести к виду:
то сервер останавливается безо всяких ошибок. Примеры использования ф-ий для работы с сетью смотрел на MSDN и все сделал по аналогии.
Получается, что из-за использования ф-ии recv() возникают какие-то побочные эффекты.
Есть ли у кого-нибудь идеи как решить проблему?