更新MQL4 600和命名管道

 

你好。

在最近的更新之后,我现在无法从我的MT4终端的一个实例中捕获调用计数,并将其转发到另一个MT4上。 你能告诉我在更新中发生了什么变化,导致这个问题吗? 以下是代码,在Build 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"函数 不再被支持,你将不得不使用 "W "宽版本的函数,如 "CreateNamedPipeW "而不是 "CreateNamedPipeA"。

 
sksyen:

谢谢你的回复,我为没有将SRC作为文件粘贴而道歉。

关于你的回答,这是否意味着我只需要将命名的管道 "A "的引用改为 "W"?我试着查找了一些关于这个问题的帖子,但没有找到--非常感谢您的帮助。再次感谢。

这不是把源码作为文件粘贴,而是使用SRC工具把代码放在论坛这里。 如何使用SRC按钮。( 由 "RaptorUK "提供)

这里有几个关于广义版本的函数的类似困境的参考资料。

 

谢谢你。 服务器端现在能够在更新命名的管道"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 "似乎太容易了。在新的架构和Unicode功能的变化方面,可能还有其他因素也需要解决。

然而,我不知道这是否是一个错误,因为我从来没有在MT4中使用命名管道,但你的 "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,下次再编辑 你的原帖