I would recommend you to use memory mapped files:
https://www.mql5.com/en/code/818
https://www.mql5.com/en/code/817
https://www.mql5.com/en/code/10568

- votes: 29
- 2012.01.16
- o_O
- www.mql5.com
I would recommend you to use memory mapped files:
https://www.mql5.com/en/code/818
https://www.mql5.com/en/code/817
https://www.mql5.com/en/code/10568
Thanks for your fast answer, Carl. MMF seems to be much easier than what i did -wasted a whole weekend. I have not read the entire .mqh. Do i need something like a semaphore or is something like that included in the .mqh?
Sorry, I haven't worked with them yet - you have to try yourself. But I guess you have to define your own access management!
I would recommend to have only one directional mm-files means A only writes into f1 and only reads from f1 and as soon B reads from f1 it deletes its content. So that A 'adds' its text (either f1 is empty or it is added at the end) and B reads the whole content all the time and empties it. And as soon as one them accesses f1 it is blocked - which will take take only fractals of mSec.
Sorry, I haven't worked with them yet - you have to try yourself. But I guess you have to define your own access management!
I would recommend to have only one directional mm-files means A only writes into f1 and only reads from f1 and as soon B reads from f1 it deletes its content. So that A 'adds' its text (either f1 is empty or it is added at the end) and B reads the whole content all the time and empties it. And as soon as one them accesses f1 it is blocked - which will take take only fractals of mSec.
thanks for your help and excuse my late answer. The transfer of data works. I have done a lot of testing. Currently there is no need for a semaphore. The EA creates two instances of the provided class. Instance(A1) creates a file, only writes to it and the other terminal -instance(B2)- only reads from it. Instance(A2) opens the file the other terminal -instance(B1)- created and only reads from it. This solution is scaleable as long as there is enough RAM.
For synchronizisation purposes i have written a small include-file. It provides the local time with milliseconds.
From my current point of view synchronizisation is the hardest job. In an demo-account i have lost nearly 2200 in six minutes, just because the other demo-account stopped providing quotes and as a result both terminals got out of sync. Hopefully my new code using the small include-file will help.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
With Microsoft's help i have created a small multithreaded named pipe server. It is not finished yet. Finally i want to connect two MT4-Terminals as Client "X" (aka Client1) and as Client "Y" (aka Client2). At the moment i'am getting an unsorted output. It looks like a asynchronous communication. Perhaps you know what the problem is. Thanks in advance for your answers.
The output:
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: 29↨!
The ID of thedata is: 88↨!
The ID of thedata is: ;2↨!
The ID of thedata is: 99↨!
The ID of thedata is: 0!
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: 2987;2989 ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: 29↨!
The ID of thedata is: 86↨!
The ID of thedata is: ;2↨!
The ID of thedata is: 98↨!
The ID of thedata is: 8!
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: 2987;2989 ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: 29↨!
The ID of thedata is: 86↨!
The ID of thedata is: ;2↨!
The ID of thedata is: 98↨!
The ID of thedata is: 8!
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: 2987;2989 ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: 29↨!
The ID of thedata is: 88↨!
The ID of thedata is: ;2↨!
The ID of thedata is: 99↨!
The ID of thedata is: 0!
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: 2988.5;2990.5 ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: 29↨!
The ID of thedata is: 89↨!
The ID of thedata is: ;2↨!
The ID of thedata is: 99↨!
The ID of thedata is: 1!
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: 2988;2990 ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: X!
SENDING AN OK TO X!
I'am reading from X!
RECEIVED: ! Now I'am writing to X!
The content of Client2 is: 2: Nothing received...
Size of Client2 is: 23 ! Size of TCHAR is: 1 !
The ID of thedata is: 29↨!
The ID of thedata is: 87↨!
The ID of thedata is: ;2↨!
The ID of thedata is: 98↨!
The ID of thedata is: 9!
InstanceThread: client disconnected.
InstanceThread exitting.
...
The server(C++):
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#define BUFSIZE 512
DWORD WINAPI InstanceThread(LPVOID);
struct theStruct {
TCHAR Client1[BUFSIZE];
TCHAR Client2[BUFSIZE];
HANDLE thePipe;
};
int main(VOID)
{
BOOL fConnected = FALSE;
DWORD dwThreadId = 0;
HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\MyMT4PipeServer");
theStruct *base = (theStruct*) malloc(sizeof(theStruct));
StringCchCopy(base->Client1, 23*sizeof(TCHAR), TEXT("1: Nothing received..."));
StringCchCopy(base->Client2, 23*sizeof(TCHAR), TEXT("2: Nothing received..."));
for (;;)
{
printf("\nPipe Server: Main thread awaiting client connection on %s\n", lpszPipename);
hPipe = CreateNamedPipe(
lpszPipename, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
0, // client time-out
NULL); // default security attribute
if (hPipe == INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipe failed, GLE=%d.\n", GetLastError());
free(base);
return -1;
}
fConnected = ConnectNamedPipe(hPipe, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (fConnected)
{
printf("Client connected, creating a processing thread.\n");
base->thePipe = hPipe;
hThread = CreateThread(
NULL, // no security attribute
0, // default stack size
InstanceThread, // thread proc
base, // thread parameter
0, // not suspended
&dwThreadId); // returns thread ID
if (hThread == NULL)
{
printf("CreateThread failed, GLE=%d.\n", GetLastError());
free(base);
return -1;
}
else CloseHandle(hThread);
}
else
CloseHandle(hPipe);
}
free(base);
return 0;
}
DWORD WINAPI InstanceThread(LPVOID lpvParam)
DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0;
BOOL fSuccess = FALSE;
HANDLE hPipe = NULL;
if (lpvParam == NULL)
{
printf( "\nERROR - Pipe Server Failure:\n");
printf( " InstanceThread got an unexpected NULL value in lpvParam.\n");
printf( " InstanceThread exitting.\n");
return (DWORD)-1;
}
printf("InstanceThread created, receiving and processing messages.\n");
struct theStruct *thedata = (struct theStruct*) lpvParam;
hPipe = (HANDLE) thedata->thePipe;
while (1)
{
TCHAR theid[2];
fSuccess = ReadFile(
hPipe, // handle to pipe
theid, // buffer to receive data
2*sizeof(TCHAR), // size of buffer
&cbBytesRead, // number of bytes read
NULL); // not overlapped I/O
if (!fSuccess || cbBytesRead == 0)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
{
printf("InstanceThread: client disconnected.\n", GetLastError());
}
else
{
printf("InstanceThread ReadFile failed, GLE=%d.\n", GetLastError());
}
break;
}
printf("The ID of thedata is: %s! \n",theid);
if (_tcscmp(theid,"X") == 0) {
printf("SENDING AN OK TO X!\n");
DWORD ok = 42;
fSuccess = WriteFile(hPipe,&ok,sizeof(ok),&cbWritten,NULL);
if (!fSuccess || sizeof(ok) != cbWritten)
{
printf("InstanceThread WriteFile(int) failed, GLE=%d.\n", GetLastError());
break;
}
printf("I'am reading from X! \n");
fSuccess = ReadFile(
hPipe, // handle to pipe
thedata->Client1, // buffer to receive data
BUFSIZE*sizeof(TCHAR), // size of buffer
&cbBytesRead, // number of bytes read
NULL); // not overlapped I/O
if (!fSuccess || cbBytesRead == 0)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
{
printf("InstanceThread: client disconnected.\n", GetLastError());
}
else
{
printf("InstanceThread ReadFile failed, GLE=%d.\n", GetLastError());
}
break;
}
printf("RECEIVED: %s ! Now I'am writing to X! \n",thedata->Client1);
DWORD cl2size = lstrlen(thedata->Client2)+1;
fSuccess = WriteFile(hPipe,&cl2size,sizeof(cl2size),&cbWritten,NULL);
if (!fSuccess || sizeof(cl2size) != cbWritten)
{
printf("InstanceThread WriteFile(int) failed, GLE=%d.\n", GetLastError());
break;
}
printf("The content of Client2 is: %s \n",thedata->Client2);
DWORD sizeOfClient2 = (lstrlen(thedata->Client2)+1)*sizeof(TCHAR);
printf("Size of Client2 is: %d ! Size of TCHAR is: %d !\n",sizeOfClient2, sizeof(TCHAR));
fSuccess = WriteFile(
hPipe, // handle to pipe
thedata->Client2,// buffer to write from
sizeOfClient2, //number of bytes to write
&cbWritten, // number of bytes written
NULL); // not overlapped I/O
if (!fSuccess || sizeOfClient2 != cbWritten)
{
printf("InstanceThread WriteFile(str) failed, GLE=%d.\n", GetLastError());
break;
}
} else if (_tcscmp(theid,"Y") == 0) {
// Not finished yet. See "X" for further details.
}
}
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
printf("InstanceThread exitting.\n");
return 1;
}
The client(MQL4):
//--- input parameters
input string ID="X";
int fHandle;
string receive = "NOTHING YET!";
void contact () {
FileWriteString(fHandle,ID,StringLen(ID)+1);
FileFlush(fHandle);
FileSeek(fHandle,0,SEEK_SET);
int getOK = FileReadInteger(fHandle);
FileFlush(fHandle);
FileSeek(fHandle,0,SEEK_SET);
if (getOK == 42) {
string send = Bid + ";" + Ask;
//Print(send);
FileWriteString(fHandle,send,StringLen(send)+1);
FileFlush(fHandle);
FileSeek(fHandle,0,SEEK_SET);
int getsize = FileReadInteger(fHandle);
//FileFlush(fHandle);
//FileSeek(fHandle,0,SEEK_SET);
receive = FileReadString(fHandle,getsize);
FileFlush(fHandle);
FileSeek(fHandle,0,SEEK_SET);
}
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
fHandle = FileOpen("\\\\.\\pipe\\MyMT4PipeServer",
FILE_READ|FILE_WRITE|FILE_BIN);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
FileClose(fHandle);
EventKillTimer();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
contact();
Print(receive);
}
//+------------------------------------------------------------------+
...