Socket не получает данные

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
jaffer wilson
2471
jaffer wilson  
Я прикрепил библиотеку, которую я пытался создать клиент Socket в mql5.

Пожалуйста, дайте мне знать, почему я не могу получить данные, отправленные сервером сокетов

Я попытался изменить функцию, используя цикл while. Он работает некоторое время, но изменяет MT5 после 2 или 3 попыток. См. Код:

 string ClientSocket::Receive( string MessageSeparator = "" )
{
   if (!mConnected) return "" ;
   //Sleep(200);
   string strRetval = "" ;
   
   uchar arrBuffer[];
   int BufferSize = 10000 ;
   ArrayResize (arrBuffer, BufferSize);

   uint nonblock = 1 ;
   if ( TerminalInfoInteger ( TERMINAL_X64 )) {
      ioctlsocket(mSocket64, FIONBIO, nonblock);
 
       int res = 1 ;
       while (res > 0 ) {
         res = recv(mSocket64, arrBuffer, BufferSize, 0 );
         //Print(res);
         while (res < 0 )
         {
         res = recv(mSocket64, arrBuffer, BufferSize, 0 );
         //Print(res);
         }
         
         //Print(res);
         //Print(WSAGetLastError());
         if (res > 0 ) {
             StringAdd (mPendingReceiveData, CharArrayToString (arrBuffer, 0 , res));
             //ArrayPrint(arrBuffer);
         } else {
         //Print(res, "false");
             if (WSAGetLastError() != WSAWOULDBLOCK) mConnected = false ;
         }
      }
   } else {
      ioctlsocket(mSocket32, FIONBIO, nonblock);

       int res = 1 ;
       while (res > 0 ) {
         res = recv(mSocket32, arrBuffer, BufferSize, 0 );
         
         if (res > 0 ) {
             StringAdd (mPendingReceiveData, CharArrayToString (arrBuffer, 0 , res));
         } else {
             if (WSAGetLastError() != WSAWOULDBLOCK) mConnected = false ;
         }
      }
   }   
   
   if (mPendingReceiveData == "" ) {
       // No data
      
   } else if (MessageSeparator == "" ) {
       // No requested message separator to wait for
      strRetval = mPendingReceiveData;
      mPendingReceiveData = "" ;;
   
   } else {
       int idx = StringFind (mPendingReceiveData, MessageSeparator);
       if (idx >= 0 ) {
         while (idx == 0 ) {
            mPendingReceiveData = StringSubstr (mPendingReceiveData, idx + StringLen (MessageSeparator));
            idx = StringFind (mPendingReceiveData, MessageSeparator);
         }
         
         strRetval = StringSubstr (mPendingReceiveData, 0 , idx);
         mPendingReceiveData = StringSubstr (mPendingReceiveData, idx + StringLen (MessageSeparator));
      }
   }
   ArrayFree (arrBuffer);
   return strRetval;
}


Файлы:
jaffer wilson
2471
jaffer wilson  
Пожалуйста, помогите мне. Я застрял в этой проблеме.
pavlick_
773
pavlick_  
Я вашу библиотеку копать не буду (шибко жирная), но могу выложить сюда свой tcp клиент если интересно (150 строк кода примерно, сервер на mql не писал, он во внешнем приложении). Кстати это может помочь https://www.mql5.com/ru/articles/2599
jaffer wilson
2471
jaffer wilson  
pavlick_ :
I will not dig your library (very fat), but I can put my tcp client here if interested (approximately 150 lines of code, the server did not write to mql, it is in external application) By the way, this can help  https://www.mql5.com/en/articles/2599

Вы можете поделиться своим клиентом tcp? Это будет полезно.

pavlick_
773
pavlick_  
 class TCP_Client
{
  SOCKET socket;
   uchar state;
  TCP_Client( const TCP_Client&);
  TCP_Client operator =(TCP_Client &);
public :
   // Address in the "IPv4:port" format.
  TCP_Client( string server_address);
  ~TCP_Client();
   // Return true if the client is connected.
   bool good() const ;
   // Receives a data block.
   // At the beginning of each block there must be 4 bytes of int, value
   // of which is equal to block size. After size there is sizeof(prefix)
   // which identifies type of received data in buf. Returns size of 
   // received block (prefix + buf) or 0.
   int recv( uchar &prefix, uchar &buf[]);
   // Sends a block, which is constituted from
   // "prefix + buf[0 : (cnt - 1)]", if cnt > ArraySize(buf) then
   // all array's ellements are included in the block. Function adds
   // 4 byte title which equal to block size . Each buf type
   // requires existence of appropriate send() in #import section. 
   // Returns byte size of sent block or 0.
   template < typename _T>
   int send( uchar prefix, _T &buf[], int cnt = INT_MAX );
};

Пример:

 #define  SERVER_IP_PORT     "127.0.0.1:10500"
#define  PRINT             Alert
#define  X64
#include  <myincl\tcp_client.mqh>

struct Trade_order
{
   char symbol[ 28 ];
   int cmd;               // 0 - buy stop, 1 - sell stop
   double volume;
   double price;
   double stoploss;       // or 0
   double takeprofit;     // or 0
   double cancel_price;   // or 0
};
#import  "msvcrt.dll"
// For each recived type declare memcpy function.
  UINTPTR memcpy(Trade_order &dest, const uchar &src[], size_t count);
#import

 struct Reply
{
   int data;
};
#import  "ws2_32.dll"
// For each user sent type declare send function.
   int send(SOCKET s, const Reply &buf[], int len, int flags);
#import


 TCP_Client *tcp_client = NULL ;

//------- handlers------------------------------------
void prefix0_handler( const uchar &read_buf[], int read)
{
   Trade_order order = {};
   memcpy(order, read_buf, read);
   //...
   
   // sending reply
   Reply r[ 1 ]; r[ 0 ].data = 0 ;
   tcp_client.send( 0 , r);
   return ;
}
void prefix1_handler( const uchar &read_buf[], int read)
{
}
//...
//----------------------------------------------------

void OnTick ()
{
   // it is blocking socket, i don't need other.
   tcp_client = new TCP_Client(SERVER_IP_PORT);
   if (tcp_client == NULL )
     return ;
    
   uchar read_buf[];
   // block is executed if connected
   if ( tcp_client.good() )
     while ( ! IsStopped () )
     {
       uchar prefix = 0 ;
       int read = tcp_client.recv(prefix, read_buf);
       if (read == 0 )
       {
         PRINT( "Connection is broken" );
         break ;
       }
      
       switch (prefix)
       {
       case 0 : prefix0_handler(read_buf, read - sizeof (prefix)); break ;
       case 1 : prefix1_handler(read_buf, read - sizeof (prefix)); break ;
       default : PRINT( "Command from server has unknown type = " , prefix);
       }
     }
   delete tcp_client;
}
Примечание: он блокирует клиента (если в соке нет входящих данных, вызов recv () блокирует и ожидает получения данных).
Файлы:
jaffer wilson
2471
jaffer wilson  
pavlick_ :

Example:

Итак, ваш TCP-клиент работает нормально? Я попробую и дам вам знать моего друга. Спасибо за файл.

pavlick_
773
pavlick_  
jaffer wilson :

Итак, ваш TCP-клиент работает нормально? Я попробую и дам вам знать моего друга. Спасибо за файл.

работал, но я тестировал его только на x32.

jaffer wilson
2471
jaffer wilson  
pavlick_ :

it worked, but I tested it only on x32.

Спасибо, но это не сработало для меня. Он висит мой MT5

pavlick_
773
pavlick_  
#define  X64

Обратите на это внимание, если архитектура не 64 битная, то

#define  X32

[quote]Спасибо, но это не сработало для меня. Он висит мой MT5[/quote]

Странно, сообщение о подключении появлялось? Если да, то клиент ждёт данне от сервера (blocking i/o). Я у себя только что запустил на x64 - работает.

jaffer wilson
2471
jaffer wilson  
pavlick_ :

Pay attention to this, if the architecture is not 64 bit, then

[quote] Thanks, but that didn't work for me. It hangs my MT5 [/ quote]

Strange, the connection message appeared? If so, the client waits for this data from the server (blocking i / o). I just started it on x64 - it works.

Хорошо, я проверю это и могу быть моим последним вопросом на форуме MQL5.com. Люди заинтересованы в том, чтобы высмеять других, которые немного не понимают часть кодирования и вместо этого пытаются доминировать над ними, потому что у них есть знания.

Не обижайся с тобой, друг мой. Но есть и другие. Спасибо за ваш ответ.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий