Discussão do artigo "Comunicando-se com o MetaTrader 5 utilizando pipes nomeados sem DLLs" - página 4

 
Renat:
Ao transmitir cadeias de caracteres, 4 bytes de seu tamanho vão primeiro.

Corrigida a função de recebimento de dados com a especificação do tamanho explícito do buffer.

Entendi o motivo pelo qual a transferência reversa não funcionou - não especifiquei o tamanho dos dados transferidos.

Muito obrigado. Tudo funcionou.

Os pipes são poderosos. Respeito ao autor do artigo.

 
Renat:
Isso foi feito na última versão do MetaTrader 4.
Peço desculpas, achei que tinha deixado passar alguma coisa. Dei uma olhada no anúncio 445 - de fato, há cerca de pips lá. A questão é que não há nenhuma palavra sobre isso na ajuda. Haverá alguma atualização sobre esse assunto, e quando? Talvez você possa descrevê-lo no fórum.
 

Os pipes no 4 funcionam de forma semelhante ao 5, também por meio de operações de arquivo.

Lançaremos um artigo sobre o MT4.

 
Renat:

Os pipes no 4 funcionam de forma semelhante ao 5, também por meio de operações de arquivo.

Lançaremos um artigo para o MT4.

Olá, posso ter um exemplo simples para o MT4? Não estou contando com um artigo, é claro.

Estou especificamente interessado em como ler três parâmetros de meu programa escrito por mim mesmo em um Expert Advisor no terminal.

 
Renat:
Ele foi feito na última versão do MetaTrader 4.

Tudo parece funcionar bem no MT5.

O único ponto:

  • Seria bom fazer com que, ao tentar ler do canal usando ReadString e outros métodos, a integridade do canal pipe fosse verificada primeiro.

Caso contrário, ficaremos pendurados no método WaitForRead indefinidamente, embora o lado do servidor tenha sido fechado há muito tempo. Tudo isso foi verificado no Win7-64.

Adicionei o tempo limite e alguns outros truques ao método WaitForRead no lado do servidor e obtive um sistema funcional com reconexões automáticas em ambos os lados do canal,

mas tudo isso é um pouco "muleta".

 
Dima_S:

Tudo parece estar funcionando bem no MT5.

O único ponto:

  • Seria bom fazer com que, ao tentar ler do canal usando ReadString e outros métodos, a integridade do canal pipe seja verificada primeiro.

Caso contrário, ficaremos pendurados no método WaitForRead indefinidamente, embora o lado do servidor tenha sido fechado há muito tempo. Tudo isso foi verificado no Win7-64.

Adicionei o tempo limite e alguns outros truques ao método WaitForRead no lado do servidor e obtive um sistema funcional com reconexões automáticas em ambos os lados do canal,

mas tudo isso é um pouco "muleta".

Do nosso lado, foi uma demonstração da possibilidade.

Publique sua variante da classe. Nós finalizaremos a classe padrão.

 
Na verdade, adicionei apenas o método WaitForRead com verificação de erros e saída por tempo limite (tempo de espera - em unidades convencionais - número de intervalos de cerca de 20 ms):
bool
CFilePipe::WaitForRead( const ulong size, const int _time_out )
{
  int  count = 0;

  while( count < _time_out && m_handle != INVALID_HANDLE && !IsStopped( ))
  {
    if( FileSize( m_handle ) >= size )
    {
     return( true );
    }
    else if( GetLastError( ) != 0 )
    {
      return( false );
    }
    Sleep( 1 );
    count++;
  }

  return( false );
}


A parte do cliente em si é mais ou menos assim:

while( !IsStopped( ))
{
// Tentando se conectar ao servidor PIPE:
  Print( "Try to connect" );
  if( pipe_Ptr.Open( ch_name, FILE_READ | FILE_WRITE | FILE_ANSI ) != INVALID_HANDLE )
  {
    if( IsStopped( ))
    {
      pipe_Ptr.Close( );
      return;
    }
    Print( "Pipe " + ch_name + " opened" );

// Ciclo de recepção de dados:
    while( !IsStopped( ))
    {
// Verificar a integridade da conexão:
      if( !pipe_Ptr.WriteString( "@" ))
      {
        Print( "Disconnected: ", GetLastError( ));
        pipe_Ptr.Close( );
        break;
      }

// Recuperação de dados:
      if( pipe_Ptr.WaitForRead( sizeof( int ), 100 ))
      {
        if( !pipe_Ptr.ReadString( str ))
        {
          Print( "Reading string failed: ", GetLastError( ));
          pipe_Ptr.Close( );
          break;
        }
        Print( "Server: ", str, " received" );
      }
    }
  }
  Sleep( 1000 );
}

A questão é que o método FileSize, que é usado enquanto se aguarda a chegada dos dados, não detecta uma violação de conexão (aparentemente, ele não verifica).

O tempo limite ajuda, mas, na minha opinião, não em todas as situações possíveis. Seria bom verificar todos esses erros no método FileSize.

 

Estranho...

As imagens do buffer não entram nos comentários e, exatamente se você usar alt+PrntScr e colá-las no editor, a imagem é inserida, mas a mensagem não entra na ramificação.

Certo, o problema é que o exemplo de teste do artigo não é executado

Mas no terminal, o script não registra nada até que eu o exclua do gráfico.

E então eu vejo no registro

2013.03.26 15:33:11     PipeClient (EURUSD,M5)  Client: sending welcome message failed
2013.03.26 15:33:11     PipeClient (EURUSD,M5)  Client: pipe opened

Win7x64 build 787 datado de 21 de março de 2013

 

Acabei de verificar, tudo funciona.


No MQ5, você só precisa substituir a linha

uint items=ExtPipe.ReadDoubleArray(buffer);

на 

uint items=ExtPipe.ReadArray(buffer);
 
Renat:

Acabei de verificar, tudo funciona.


No MQ5, você só precisa substituir a linha

Eu não tenho ...

Substituí a linha ou ele não compilaria.