MQL4 600 및 명명된 파이프 업데이트

 

여보세요,

이 최근 업데이트 이후에는 다른 MT4로 중계하기 위해 MT4 터미널의 한 인스턴스에서 호출 수를 캡처할 수 없습니다. 이 문제를 일으키는 업데이트에서 변경된 사항을 알려주실 수 있습니까? 다음은 빌드 509에서 계속 잘 작동하지만 최근 업데이트 이후에는 작동하지 않는 코드입니다.


 extern string PipeName = "MetaTerminal1" ;

extern int SuspendSeconds = 10 ;

extern int SleepMS = 10 ;







#define PIPE_BASE_NAME "\\\\.\\pipe\\mt4-"



#define GENERIC_READ 0x80000000

#define GENERIC_WRITE 0x40000000

#define PIPE_ACCESS_DUPLEX 3

#define PIPE_UNLIMITED_INSTANCES 255

#define PIPE_NOWAIT 1

#define PIPE_TYPE_MESSAGE 4

#define PIPE_READMODE_MESSAGE 2

#define PIPE_WAIT 0



#import "kernel32.dll"

int CreateNamedPipeA( string pipeName, int openMode, int pipeMode, int maxInstances, int outBufferSize, int inBufferSize, int defaultTimeOut, int security);

int PeekNamedPipe( int PipeHandle, int PassAsZero, int PassAsZero2, int PassAsZero3, int & BytesAvailable[], int PassAsZero4);

int CreateFileA( string Filename, int AccessMode, int ShareMode, int PassAsZero, int CreationMode, int FlagsAndAttributes, int AlsoPassAsZero);

int CloseHandle( int fileHandle);

// int ReadFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesRead[], int PassAsZero);

         int ReadFile( int FileHandle, int & inBuffer[], int BufferLength, int & BytesRead[], int lpOverlapped);

int WriteFile( int FileHandle, string Buffer, int BufferLength, int & BytesWritten[], int PassAsZero);

//      int WriteFile(int FileHandle,int& inBuffer[], int NumberOfBytesToWrite, int& bytesWritten[], int lpOverlapped);

int MulDiv( string X, int N1, int N2);

#import



// Number of pipe instances to create by default. This value can overridden by the optional parameter to

// CreatePipeServer(). The number of instances is in effect the maximum number of messages which

// can be sent to the server between each call which the server makes to CheckForPipeMessages().

// If more messages than this are sent, the extra messages will fail and the sender(s) will need to retry.

#define DEFAULT_MAX_PIPES 200



// Number of pipe instances to allocate. Defaults to DEFAULT_MAX_PIPES unless it is overridden

int glbPipeCount = DEFAULT_MAX_PIPES;

// Array of pipe handles allocated by CreatePipeServer()

int glbPipe[DEFAULT_MAX_PIPES];

// Persistent storage of the pipe name passed as a parameter to CreatePipeServer()

string glbPipeName;



// Starts the pipe server by creating n instances of the pipe

void CreatePipeServer( string PipeName, int UsePipeInstances = DEFAULT_MAX_PIPES)

{

// Store the number of pipe instances to use and resize the array accordinging

glbPipeCount = UsePipeInstances;

ArrayResize (glbPipe, glbPipeCount);

// Store the name to use for the pipe instances

glbPipeName = PipeName;

// Create the pipe instances

for ( int i = 0 ; i < glbPipeCount; i++)

glbPipe[i] = CreatePipeInstance();

return ;

}



// Closes all the resources used by the pipe server: i.e. closes all the pipe instances

void DestroyPipeServer()

{

for ( int i = 0 ; i < glbPipeCount; i++)

CloseHandle(glbPipe[i]);

return ;

}



// Service function which creates a pipe instance

int CreatePipeInstance()

{

string strPipeName = StringConcatenate (PIPE_BASE_NAME, glbPipeName);

return (CreateNamedPipeA(strPipeName, GENERIC_READ | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 1000 , 1000 , 0 , NULL ));

}

datetime StartTime= 0 ;

int brCall= 0 ;



int aPairCount= 0 ;

string aPair[ 1000 ];

int aDigit[ 1000 ];

datetime aLastSinhTime[ 1000 ];

double aBid[ 1000 ];

double aAsk[ 1000 ];



int init()

{

StartTime= TimeLocal ();

brCall= 0 ;

aPairCount= 0 ;



// Create the server

CreatePipeServer(PipeName);

return ( 0 );

}



int deinit()

{

// Destroy the pipe server

DestroyPipeServer();

Comment ( "" );

return ( 0 );

}



int start()

{

while (! IsStopped () && IsConnected ())    

{

for ( int i = 0 ; i < glbPipeCount; i++)

CheckPipe(i);

Comment ( "\nStart Time: " + TimeToStr (StartTime, TIME_DATE | TIME_SECONDS )+

"\nLocal Time: " + TimeToStr ( TimeLocal (), TIME_DATE | TIME_SECONDS )+

"\nCall Count: " + DoubleToStr (brCall, 0 )

);

Sleep ( MathMax (SleepMS, 10 ));

}

return ( 0 );

}



bool CheckPipe( int PipeIndex)

{

bool Result= false ;

string sMsg = "" ;

// See if there's data available on the pipe

int BytesAvailable[ 1 ] = { 0 };

int res = PeekNamedPipe(glbPipe[PipeIndex], 0 , 0 , 0 , BytesAvailable, 0 );

if (res != 0 ) {

// PeekNamedPipe() succeeded



// Is there data?

if (BytesAvailable[ 0 ] != 0 ) {

Result= true ;



// Keep reading until either we have all the data, or an error occurs

int TotalBytesRead = 0 ;

while (TotalBytesRead < BytesAvailable[ 0 ])

{

string ReadBuffer= "" ;

int iBuffer[ 256 ];

int BytesRead[ 1 ] = { 0 };

ReadFile(glbPipe[PipeIndex],iBuffer, 4 * ArraySize (iBuffer),BytesRead, NULL );

for ( int i= 0 ; i<BytesRead[ 0 ]; i++)

ReadBuffer = ReadBuffer + CharToStr ( (iBuffer[i/ 4 ] >> ((i & 3 )* 8 )) & 0xff );

// Did we get any data from the read?

if (BytesRead[ 0 ] > 0 )

{

// Yes, got some data. Add it to the total message which is passed back

sMsg = StringConcatenate (sMsg, StringSubstr (ReadBuffer, 0 , BytesRead[ 0 ]));

TotalBytesRead += BytesRead[ 0 ];

}

else

{

// No, the read failed. Stop reading, and pass back an empty string

sMsg = "" ;

TotalBytesRead = 999999 ;

}

}

if ( StringLen (sMsg)> 0 )

{

string outString= "n/a" ;

RefreshRates ();

brCall=brCall+ 1 ;

double pBid= MarketInfo (sMsg, MODE_BID );

double pAsk= MarketInfo (sMsg, MODE_ASK );

if (pBid> 0.0001 && pAsk> 0.0001 )

{

int ai= 0 ;

bool fl= true ;

for (i= 1 ;i<=aPairCount;i++)

if (aPair[i]==sMsg)

{

ai=i;

break ;

}

if (ai== 0 )

{

aPairCount=aPairCount+ 1 ;

ai=aPairCount;

aPair[ai]=sMsg;

aDigit[ai]= MarketInfo (sMsg, MODE_DIGITS );

aLastSinhTime[ai]= TimeLocal ();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if ( MathAbs (aBid[ai]-pBid)>= 0.00001 || MathAbs (aAsk[ai]-pAsk)>= 0.00001 )

{

aLastSinhTime[ai]= TimeLocal ();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if ( TimeLocal ()-aLastSinhTime[ai]>SuspendSeconds)

fl= false ;

if (fl)

outString= DoubleToStr (aBid[ai],aDigit[ai])+ "|" + DoubleToStr (aAsk[ai],aDigit[ai]);

else

outString= "Suspended" ;

}



int bytesWritten[ 1 ];

bool fSuccess=WriteFile(glbPipe[PipeIndex],outString, StringLen (outString)+ 1 ,bytesWritten, NULL ) != 0 ;

if (!fSuccess || bytesWritten[ 0 ] != StringLen (outString)+ 1 )

{

Sleep ( 10 );

}

}

// Destroy and recreate the pipe instance

CloseHandle(glbPipe[PipeIndex]);

glbPipe[PipeIndex] = CreatePipeInstance();

} else {

// No data available on pipe

}

} else {

// PeekNamedPipe() failed

}

return (Result);

}
 

SRC 버튼을 사용하여 코드를 배치하십시오. 그렇지 않으면 중재자가 코드를 삭제할 것입니다!

또한 "A" 기능 이 더 이상 지원되지 않으며 "CreateNamedPipeA" 대신 "CreateNamedPipeW"와 같은 기능의 "W" 와이드 버전을 사용하게 될 것이라고 언급한 다른 많은 스레드를 읽으십시오.

 
sksyen :

답장해주셔서 감사하고 SRC를 파일로 붙여넣지 않은 것에 대해 사과드립니다.

귀하의 응답과 관련하여 이것은 명명된 파이프 "A" 참조를 "W"로 변경해야 한다는 것을 의미합니까? 이와 관련하여 몇 가지 스레드를 찾아보았지만 찾을 수 없었습니다. 귀하의 도움에 감사드립니다. 다시 한번 감사합니다.

소스를 파일로 붙여넣는 것이 아니라 SRC 도구를 사용하여 여기 포럼에 코드를 배치하는 것입니다. SRC 버튼을 사용하는 방법. (제공 '랩터UK')

다음은 기능의 와이드 버전과 유사한 딜레마에 대한 몇 가지 참조입니다.

 

고맙습니다. 이제 서버 측에서는 명명된 파이프 "A"를 "W'로 업데이트한 후 호출 수를 캡처할 수 있습니다. 그러나 MT4의 다른 인스턴스에서 정보 입력을 수신하는 데 문제가 있는 것으로 보입니다. 업데이트했습니다. 이름은 수신 측에서 'W'로 연결되지만 여전히 어떤 이유로 데이터를 가져오지 못합니다. 아이디어가 있습니까? 수신 측의 코드는 아래를 참조하십시오.

extern double MaxDD          = 30 ;
extern double MM             = 30 ;

extern string PipeName       = "Terminal" ;
extern string ServerPairName = "" ;
extern double BidCorrection  = 0 ;
extern double AskCorrection  = 0 ;

extern int     APips     = 2 ;
extern int     TPips     = 5 ;
extern int     StopPips       = 15 ;
extern int     VirtualStops   = false ;

extern int     ConfirmMS     = 20 ;
extern int     SleepMS       = 20 ;
extern int     Slippage      = 1 ;    
extern int     Magic         = 2013 ; 


#define PIPE_BASE_NAME     "\\\\.\\pipe\\mt4-"      // MUST tally with client code
#define ERROR_MORE_DATA 234

#import "kernel32.dll"
         int CallNamedPipeW( string PipeName, string outBuffer, int outBufferSz, int & inBuffer[], int inBufferSz, int & bytesRead[], int timeOut);
#import


datetime StartTime= 0 ;
double    MinLots= 0.1 ;
double    MaxLots= 0.1 ;
double    LotStep= 0.1 ;
double    MyPoint= 0.0001 ;

string    MasterPair= "" ;
double    MaxBalance= 0 ;
double    TotalPips= 0 ;
int       TotalTrades= 0 ;
double    EntrySlippage= 0 ;
int       EntryMS= 0 ;
int       OpenErrors= 0 ;


int       LastTicket= 0 ;
double    MasterBid= 0 ;
double    MasterAsk= 0 ;

string    LastQ= "" ;
           
int init()
  {
   Comment ( "Initialization ..." );
   if ( StringLen (ServerPairName)>= 1 )
      MasterPair=ServerPairName;
   else
      MasterPair= Symbol ();

   StartTime= 0 ;
   return ( 0 );
  }

int deinit()
  {
   Comment ( "" );
   return ( 0 );
  }

int start()
  {
   double CurrentPips= 0 ;
   string sInfo= "" ;
   if ( IsStopped () || ! IsConnected ())
       return ( 0 );

   if ( Digits <= 3 )
      MyPoint= 0.01 ;
   MinLots= MarketInfo ( Symbol (), MODE_MINLOT );
   MaxLots= MarketInfo ( Symbol (), MODE_MAXLOT );
   LotStep= MarketInfo ( Symbol (), MODE_LOTSTEP );

   if (StartTime<= 0 )
     {
      MaxBalance= AccountBalance ();
      StartTime= TimeLocal ();
      TotalPips= 0 ;
      EntrySlippage= 0 ;
      TotalTrades= 0 ;
      EntryMS= 0 ;
      LastTicket= 0 ;
      OpenErrors= 0 ;
     }

   while (! IsStopped ())  
     {
       RefreshRates ();
       double dBid= Bid ;
       double dAsk= Ask ;
       int OldTicket=LastTicket;
      LastTicket= 0 ;
       for ( int j= OrdersTotal ()- 1 ; j>= 0 ; j--) 
           if ( OrderSelect (j, SELECT_BY_POS , MODE_TRADES ))
             if (( OrderSymbol () == Symbol ()) && ( OrderMagicNumber () == Magic))
              {
               if ( OrderType ()== OP_BUY )
                  CurrentPips=dBid- OrderOpenPrice ();
               else
                  CurrentPips= OrderOpenPrice ()-dAsk;
               CurrentPips=CurrentPips/MyPoint;
               LastTicket= OrderTicket ();
          

              }

       if (LastTicket== 0 && OldTicket> 0 )
         if ( OrderSelect (OldTicket, SELECT_BY_TICKET , MODE_HISTORY ))
           {
             if ( OrderType ()== OP_BUY )
               TotalPips=TotalPips+( OrderClosePrice ()- OrderOpenPrice ())/MyPoint;
             else
               TotalPips=TotalPips+( OrderOpenPrice ()- OrderClosePrice ())/MyPoint;
           }

      MaxBalance= MathMax (MaxBalance, AccountBalance ());
       if ( AccountBalance ()<= 0 )
         break ;
      sInfo= "" ;
      CheckMaster();
       if (MaxDD<= 100 *(MaxBalance- AccountBalance ())/MaxBalance)
         sInfo=sInfo+ "\nMaximum Drawdawn Reached !!!" ;
       else    
       if (MasterBid>= Point && MasterAsk>= Point )
         sInfo=sInfo+ "\nBuy/Sell Levels: " + DoubleToStr ((MasterBid-dAsk)/MyPoint-APips, 1 )+ " / " + DoubleToStr ((dBid-MasterAsk)/MyPoint-APips, 1 )+ " pips" ;
       else
       if ( StringLen (LastQ)> 0 )
         sInfo=sInfo+ "\nServer: " +LastQ;
       else
         sInfo=sInfo+ "\nServer not working !!!" ;

       if (LastTicket> 0 )
         sInfo=sInfo+ ", Position: " + DoubleToStr (CurrentPips, 1 )+ " pips" ;
       else
       if (MasterBid>= Point && MasterAsk>= Point && MaxDD> 100 *(MaxBalance- AccountBalance ())/MaxBalance)
        {
         bool Oper=- 1 ;
         if ((dAsk)>= 1.0000 )
            Oper= OP_BUY ;
         else
         if ((dBid)>= 1.0000 )
            Oper= OP_SELL ;
         if (Oper!=- 1 && ConfirmMS> 0 )
           {
             Sleep (ConfirmMS);
             RefreshRates ();
            dBid= Bid ;
            dAsk= Ask ;
            CheckMaster();
             if (Oper== OP_BUY )
               Oper=- 1 ;
             if (Oper== OP_SELL )
               Oper=- 1 ;
           }
         if (Oper!=- 1 && IsTradeContextBusy ()== false )
           {
             double Lots= MathMax (MinLots, MathMin (MaxLots, MathCeil ((MM/ 100 )* AccountFreeMargin ()/LotStep/( 100000 / 100 ))*LotStep));
             int ExecutionTime= GetTickCount ();
             if (Oper== OP_BUY )
               LastTicket= OrderSend ( Symbol (), OP_BUY , Lots, NormalizeDouble (dAsk, Digits ), Slippage*MyPoint/ Point , 0 , 0 , "" , Magic, 0 ,Blue);
             else    
               LastTicket= OrderSend ( Symbol (), OP_SELL , Lots, NormalizeDouble (dBid, Digits ), Slippage*MyPoint/ Point , 0 , 0 , "" , Magic, 0 ,Red);
            ExecutionTime= GetTickCount ()-ExecutionTime;   
             if (LastTicket< 0 )
              {
               OpenErrors=OpenErrors+ 1 ;
              }
             else
              {
               TotalTrades=TotalTrades+ 1 ;
               EntryMS=EntryMS+ExecutionTime;
               if ( OrderSelect (LastTicket, SELECT_BY_TICKET ))
                   if ( OrderType ()== OP_BUY )
                     EntrySlippage=EntrySlippage+(dAsk- OrderOpenPrice ())/MyPoint;
                   else    
                     EntrySlippage=EntrySlippage+( OrderOpenPrice ()-dBid)/MyPoint;
              }
           }
        }

       Comment ( "\nMagic# " + DoubleToStr (Magic, 0 )+ ", MM " + DoubleToStr (MM, 2 )+ ", Max DD: " + DoubleToStr (MaxDD, 1 )+ "%, Current Drawdawn: " + DoubleToStr ( 100 *(MaxBalance- AccountBalance ())/MaxBalance, 1 )+ " %" +
               "\nMin Lot " + DoubleToStr (MinLots, 2 )+ ", Max Lot " + DoubleToStr (MaxLots, 2 )+ ", Lot Step " + DoubleToStr (LotStep, 2 )+ ", Stop Level " + DoubleToStr ( MarketInfo ( Symbol (), MODE_STOPLEVEL )* Point /MyPoint, 1 )+ " pips" +
               "\n" +sInfo+
               "\nStart Time: " + TimeToStr (StartTime, TIME_DATE | TIME_SECONDS )+
               "\nLocal Time: " + TimeToStr ( TimeLocal (), TIME_DATE | TIME_SECONDS )+
               "\nTotal Pips: " + DoubleToStr (TotalPips, 1 )+
               "\nTotal Trades: " + DoubleToStr (TotalTrades, 0 )+
               "\nEntry Errors: " + DoubleToStr (OpenErrors, 0 )+
               "\nOpen Slippage: " + DoubleToStr (EntrySlippage, 1 )+ " pips" +
               "\nAverage Speed: " + DoubleToStr (EntryMS/ MathMax (TotalTrades, 1 ), 0 )+ " ms" +
               "\nAverage Slippage: " + DoubleToStr (EntrySlippage/ MathMax (TotalTrades, 1 ), 1 )+ " pips"
             );
       Sleep ( MathMax (SleepMS, 10 ));
       if ( IsTesting ())
         break ;
     }
   return ( 0 );
  }

void CheckMaster()
  {
   MasterBid= 0 ;
   MasterAsk= 0 ;
   LastQ= "" ;
   if ( IsTesting ())
     {
      MasterBid= NormalizeDouble ( MarketInfo (MasterPair, MODE_BID )/ 2 + MarketInfo (MasterPair, MODE_ASK )/ 2 -MyPoint+ 2 *MyPoint*( MathRand ()- 32767 / 2 )/( 32767 / 6 ), Digits );
      MasterAsk=MasterBid+ 2 *MyPoint;
     }
   else
     {
       string MyPipeName = PIPE_BASE_NAME+PipeName;
       int inBuffer[ 2048 ];
       int bytesRead[ 1 ];
       string extMessage = MasterPair;
       bool fSuccess = CallNamedPipeW(MyPipeName,extMessage, StringLen (extMessage)+ 1 ,inBuffer, 4 * ArraySize (inBuffer),bytesRead, 0 ) != 0 ;
       int lastError = GetLastError();
       if (fSuccess /* || lastError == ERROR_MORE_DATA*/ ) 
        { 
         string inString = "" ;
         for ( int i= 0 ; i<bytesRead[ 0 ]; i++)
             inString = inString + CharToStr ( (inBuffer[i/ 4 ] >> ((i & 3 )* 8 )) & 0xff );
         int ai= StringFind (inString, "|" , 0 );
         if (ai> 0 )
           {
            MasterBid= StrToDouble ( StringSubstr (inString, 0 , ai));
            MasterAsk= StrToDouble ( StringSubstr (inString, ai+ 1 ));
           }
         LastQ=inString;  
        }
     }
   if (MasterBid> 0.0001 )
      MasterBid=MasterBid+BidCorrection;
   if (MasterAsk> 0.0001 )
      MasterAsk=MasterAsk+AskCorrection;
  }
 
사전 공지로, 외부 문자열 PipeName에서 MetaTerminal1을 호출하도록 코드를 변경했지만 데이터와 기능 은 여전히 제대로 작동하지 않습니다. 'CreateNamedPip' 및 'CreateFile'에 대해 'A'를 'W'로 변경하는 것 외에는 조정이 필요한 코드가 있습니까?
 

"A"를 "W"로 변경하는 것은 너무 쉬워 보일 수 있습니다. 새로운 아키텍처 및 유니코드 기능의 변경과 관련하여 해결해야 하는 다른 요소도 있을 수 있습니다.

그러나 MT4에서 Named Pipes 를 사용한 적이 없기 때문에 이것이 버그인지 아닌지는 알 수 없지만 "inBuffer"와 "outBuffer"("CallNamedPipeW"에서)는 다른 유형(하나는 "문자열"이고 다른 하나는 "int"입니다). 그것은 옳지 않은 것 같습니다.

실제로 긁어 보면 MetaTrader의 이상한 트릭을 통해 DLL 상호 작용을 수행하는 것이 완전히 정확할 수 있습니다.

그 부분은 MT4-DLL 인터페이스에 정통한 사람에게 맡기겠습니다.

 
"sksyen", SRC 섹션에 코드가 포함되도록 원래 게시물을 변경할 수 있습니까? 중재자 중 한 명이 이 문제를 해결하면 게시물의 해당 부분을 삭제하고 어쨌든 제대로 하라고 요청할 것입니다. 따라서 코드를 붙여넣기 위해 다시 검색해야 하기 전에 지금 수행하십시오.
 

MT4 최신 릴리스의 명명된 파이프 에도 문제가 있습니다.

WaitNamedPipeA를 WaitNamedPipeW로 변경했으며 이제 작동합니다.

f (!WaitNamedPipeW( FullPipeName, 1 ))

{
Comment ( TimeToStr ( TimeLocal (), TIME_DATE | TIME_MINUTES | TIME_SECONDS ) + " " + PipeName + " not available" ); 
Sleep ( 1000 );
continue ;
}


그러나 CreateFileA 또는 CreateFileW를 사용하면 두 호출 모두 영구적으로 중단됩니다.


PipeHandle = CreateFileA(FullPipeName, GenericRead, 0, NULL, OPEN_EXISTING, 0, NULL);


어떤 아이디어/솔루션이 있습니까?

 
chalky66 :

MT4 최신 릴리스의 명명된 파이프에도 문제가 있습니다.

WaitNamedPipeA를 WaitNamedPipeW로 변경했으며 이제 작동합니다.

나중에 SRC 버튼 을 사용하는 것을 잊지 마십시오. . .
 

여기에 원래 게시된 서버 파일이 있습니다(다음에는 SRC에 게시하는 것을 기억하겠습니다)

 extern string PipeName = "MetaTerminal1" ;

extern int SuspendSeconds = 10 ;

extern int SleepMS = 10 ;







#define PIPE_BASE_NAME "\\\\.\\pipe\\mt4-"



#define GENERIC_READ 0x80000000

#define GENERIC_WRITE 0x40000000

#define PIPE_ACCESS_DUPLEX 3

#define PIPE_UNLIMITED_INSTANCES 255

#define PIPE_NOWAIT 1

#define PIPE_TYPE_MESSAGE 4

#define PIPE_READMODE_MESSAGE 2

#define PIPE_WAIT 0



#import "kernel32.dll"

int CreateNamedPipeA( string pipeName, int openMode, int pipeMode, int maxInstances, int outBufferSize, int inBufferSize, int defaultTimeOut, int security);

int PeekNamedPipe( int PipeHandle, int PassAsZero, int PassAsZero2, int PassAsZero3, int & BytesAvailable[], int PassAsZero4);

int CreateFileA( string Filename, int AccessMode, int ShareMode, int PassAsZero, int CreationMode, int FlagsAndAttributes, int AlsoPassAsZero);

int CloseHandle( int fileHandle);

// int ReadFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesRead[], int PassAsZero);

         int ReadFile( int FileHandle, int & inBuffer[], int BufferLength, int & BytesRead[], int lpOverlapped);

int WriteFile( int FileHandle, string Buffer, int BufferLength, int & BytesWritten[], int PassAsZero);

//      int WriteFile(int FileHandle,int& inBuffer[], int NumberOfBytesToWrite, int& bytesWritten[], int lpOverlapped);

int MulDiv( string X, int N1, int N2);

#import



// Number of pipe instances to create by default. This value can overridden by the optional parameter to

// CreatePipeServer(). The number of instances is in effect the maximum number of messages which

// can be sent to the server between each call which the server makes to CheckForPipeMessages().

// If more messages than this are sent, the extra messages will fail and the sender(s) will need to retry.

#define DEFAULT_MAX_PIPES 200



// Number of pipe instances to allocate. Defaults to DEFAULT_MAX_PIPES unless it is overridden

int glbPipeCount = DEFAULT_MAX_PIPES;

// Array of pipe handles allocated by CreatePipeServer()

int glbPipe[DEFAULT_MAX_PIPES];

// Persistent storage of the pipe name passed as a parameter to CreatePipeServer()

string glbPipeName;



// Starts the pipe server by creating n instances of the pipe

void CreatePipeServer( string PipeName, int UsePipeInstances = DEFAULT_MAX_PIPES)

{

// Store the number of pipe instances to use and resize the array accordinging

glbPipeCount = UsePipeInstances;

ArrayResize (glbPipe, glbPipeCount);

// Store the name to use for the pipe instances

glbPipeName = PipeName;

// Create the pipe instances

for ( int i = 0 ; i < glbPipeCount; i++)

glbPipe[i] = CreatePipeInstance();

return ;

}



// Closes all the resources used by the pipe server: i.e. closes all the pipe instances

void DestroyPipeServer()

{

for ( int i = 0 ; i < glbPipeCount; i++)

CloseHandle(glbPipe[i]);

return ;

}



// Service function which creates a pipe instance

int CreatePipeInstance()

{

string strPipeName = StringConcatenate (PIPE_BASE_NAME, glbPipeName);

return (CreateNamedPipeA(strPipeName, GENERIC_READ | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 1000 , 1000 , 0 , NULL ));

}

datetime StartTime= 0 ;

int brCall= 0 ;



int aPairCount= 0 ;

string aPair[ 1000 ];

int aDigit[ 1000 ];

datetime aLastSinhTime[ 1000 ];

double aBid[ 1000 ];

double aAsk[ 1000 ];



int init()

{

StartTime= TimeLocal ();

brCall= 0 ;

aPairCount= 0 ;



// Create the server

CreatePipeServer(PipeName);

return ( 0 );

}



int deinit()

{

// Destroy the pipe server

DestroyPipeServer();

Comment ( "" );

return ( 0 );

}



int start()

{

while (! IsStopped () && IsConnected ())    

{

for ( int i = 0 ; i < glbPipeCount; i++)

CheckPipe(i);

Comment ( "\nStart Time: " + TimeToStr (StartTime, TIME_DATE | TIME_SECONDS )+

"\nLocal Time: " + TimeToStr ( TimeLocal (), TIME_DATE | TIME_SECONDS )+

"\nCall Count: " + DoubleToStr (brCall, 0 )

);

Sleep ( MathMax (SleepMS, 10 ));

}

return ( 0 );

}



bool CheckPipe( int PipeIndex)

{

bool Result= false ;

string sMsg = "" ;

// See if there's data available on the pipe

int BytesAvailable[ 1 ] = { 0 };

int res = PeekNamedPipe(glbPipe[PipeIndex], 0 , 0 , 0 , BytesAvailable, 0 );

if (res != 0 ) {

// PeekNamedPipe() succeeded



// Is there data?

if (BytesAvailable[ 0 ] != 0 ) {

Result= true ;



// Keep reading until either we have all the data, or an error occurs

int TotalBytesRead = 0 ;

while (TotalBytesRead < BytesAvailable[ 0 ])

{

string ReadBuffer= "" ;

int iBuffer[ 256 ];

int BytesRead[ 1 ] = { 0 };

ReadFile(glbPipe[PipeIndex],iBuffer, 4 * ArraySize (iBuffer),BytesRead, NULL );

for ( int i= 0 ; i<BytesRead[ 0 ]; i++)

ReadBuffer = ReadBuffer + CharToStr ( (iBuffer[i/ 4 ] >> ((i & 3 )* 8 )) & 0xff );

// Did we get any data from the read?

if (BytesRead[ 0 ] > 0 )

{

// Yes, got some data. Add it to the total message which is passed back

sMsg = StringConcatenate (sMsg, StringSubstr (ReadBuffer, 0 , BytesRead[ 0 ]));

TotalBytesRead += BytesRead[ 0 ];

}

else

{

// No, the read failed. Stop reading, and pass back an empty string

sMsg = "" ;

TotalBytesRead = 999999 ;

}

}

if ( StringLen (sMsg)> 0 )

{

string outString= "n/a" ;

RefreshRates ();

brCall=brCall+ 1 ;

double pBid= MarketInfo (sMsg, MODE_BID );

double pAsk= MarketInfo (sMsg, MODE_ASK );

if (pBid> 0.0001 && pAsk> 0.0001 )

{

int ai= 0 ;

bool fl= true ;

for (i= 1 ;i<=aPairCount;i++)

if (aPair[i]==sMsg)

{

ai=i;

break ;

}

if (ai== 0 )

{

aPairCount=aPairCount+ 1 ;

ai=aPairCount;

aPair[ai]=sMsg;

aDigit[ai]= MarketInfo (sMsg, MODE_DIGITS );

aLastSinhTime[ai]= TimeLocal ();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if ( MathAbs (aBid[ai]-pBid)>= 0.00001 || MathAbs (aAsk[ai]-pAsk)>= 0.00001 )

{

aLastSinhTime[ai]= TimeLocal ();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if ( TimeLocal ()-aLastSinhTime[ai]>SuspendSeconds)

fl= false ;

if (fl)

outString= DoubleToStr (aBid[ai],aDigit[ai])+ "|" + DoubleToStr (aAsk[ai],aDigit[ai]);

else

outString= "Suspended" ;

}



int bytesWritten[ 1 ];

bool fSuccess=WriteFile(glbPipe[PipeIndex],outString, StringLen (outString)+ 1 ,bytesWritten, NULL ) != 0 ;

if (!fSuccess || bytesWritten[ 0 ] != StringLen (outString)+ 1 )

{

Sleep ( 10 );

}

}

// Destroy and recreate the pipe instance

CloseHandle(glbPipe[PipeIndex]);

glbPipe[PipeIndex] = CreatePipeInstance();

} else {

// No data available on pipe

}

} else {

// PeekNamedPipe() failed

}

return (Result);

}
 
sksyen : 감사합니다. 이제 서버 측에서 할 수 있는 ...
SRC를 사용하고 다음에 원본 게시물을 편집 하세요.
사유: