Прочтите детальное описание функции SocketIsReadible и что она возвращает.
Не true/false.
Прочтите детальное описание функции SocketIsReadible и что она возвращает.
Не true/false.
Да, увидел. Но это всё равно странно, когда функция возвращает мне число больше нуля, но SocketRead всё равно не читает данные.
В общем я написал простую dll на C# и там через TcpClient всё нормально отправляется и читается. Хотел обойтись без прослойки. Надеюсь программисты доделают сокеты в mql.
Да, увидел. Но это всё равно странно, когда функция возвращает мне число больше нуля, но SocketRead всё равно не читает данные.
В общем я написал простую dll на C# и там через TcpClient всё нормально отправляется и читается. Хотел обойтись без прослойки. Надеюсь программисты доделают сокеты в mql.
А сколько вы читаете данных?
Вы можете мгновенно без ожидания прочесть только то количество байтов, которое вам вернула функция SocketIsReadable. Если попытаетесь прочесть больше, то попадете на синхронное ожидание внутри сетевой WinAPI функции.
В вашем коде явно указано "читать 100 байт вне зависимости от наличия доступных данных во входящем буфере сокета". При том, что вы сами указали "сервер отправляет только 16 байт ответа". То есть, вы четко/жестко требуете получения 100 байт и получаете закономерный таймаут. Ведь вам прислали только 16.
Сокеты в MQL5 работают правильно. Но надо знать их особенности.
А сколько вы читаете данных?
Вы можете мгновенно без ожидания прочесть только то количество байтов, которое вам вернула функция SocketIsReadable. Если попытаетесь прочесть больше, то попадете на синхронное ожидание внутри сетевой WinAPI функции.
В вашем коде явно указано "читать 100 байт вне зависимости от наличия доступных данных во входящем буфере сокета". При том, что вы сами указали "сервер отправляет только 16 байт ответа". То есть, вы четко/жестко требуете получения 100 байт и получаете закономерный таймаут. Ведь вам прислали только 16.
Сокеты в MQL5 работают правильно. Но надо знать их особенности.
Ренат, а почему не убрать ограничение на количество чтения? Зачем это ограничение, если ответ уже к нам пришёл?
Почему не отдать полный ответ и далее с ним работать по-усмотрению?
int SocketTlsRead( int socket, // сокет uchar& buffer[], // буфер для чтения данных из сокета uint buffer_maxlen // количество байт, которые нужно прочитать );
Ренат, а почему не убрать ограничение на количество чтения? Зачем это ограничение, если ответ уже к нам пришёл?
Почему не отдать полный ответ и далее с ним работать по-усмотрению?
Сразу отдавать пришедшие данные нельзя, так как TLS использует блочное декодирование вплоть до 16 кб на блок. Поэтому любая TLS реализация собирает сырые пакеты и только при возможности декодировки очередного пакета, начинает отдавать запрашивающему.
Если отдавать любой плавающий декодированный размер вместо запрошенного размера, то получится другая, даже еще более страшная проблема. Вам надо 10 байт, а вы вдруг получили 12 кб. Теперь вам нужно принимать нечеловеческие усилия для собственной буферизации и работы с этим буфером вместо прямого чтения из сокета.
С сетевыми операциями очень рекомендуется использовать четкий бинарный протокол с прямым указанием размеров. То есть, фреймовую структуру типа [size,type][...data...], чтобы на любом этапе четко знать сколько нужно читать. Для такого случая текущая реализация SocketTlsRead подходит хорошо.
А иначе остаются тормоза и неудобности нечетких протоколов типа текстового HTTP, где в реальности приходится вычитывать строку по одному символу или буферизированно/сложнее ради скорости.
Вы сами можете написать обходную функцию, которая посимвольно будет вычитывать весь доступный на текущий момент буфер. Реализация отдачи быстрая, так что особых тормозов от посимвольного чтения не будет.
В принципе, мы можем сделать возможность при указании нулевого размера выдавать весь доступный объем данных в функциях SocketRead и SocketTlsRead. Это будет гибко.
А сколько вы читаете данных?
Вы можете мгновенно без ожидания прочесть только то количество байтов, которое вам вернула функция SocketIsReadable. Если попытаетесь прочесть больше, то попадете на синхронное ожидание внутри сетевой WinAPI функции.
В вашем коде явно указано "читать 100 байт вне зависимости от наличия доступных данных во входящем буфере сокета". При том, что вы сами указали "сервер отправляет только 16 байт ответа". То есть, вы четко/жестко требуете получения 100 байт и получаете закономерный таймаут. Ведь вам прислали только 16.
Сокеты в MQL5 работают правильно. Но надо знать их особенности.
Интересная особенность, но неочевидная и неудобная. В C# эта же функция работает по-другому, она читает все данные, которые пришли и возвращает кол-во прочитанных байт. К тому же позволяет указать смещение в буфере, по которому эти данные записывать.
int SocketRead( int socket, // сокет uchar& buffer[], // буфер для чтения данных из сокета uint buffer_maxlen // количество байт, которые нужно прочитать );
buffer_maxlen - это максимальный размер буфера (у меня 100 байт), судя по имени, а не строгое количество байт, которое надо узнавать заранее у функции SocketIsReadable.
SocketIsReadable - булевская функция, судя по имени, которая просто показывает, что из сокета можно читать.
Это логично. Если в документации не так, то это очень плохо, потому как я полдня убил на то, что на первый взгляд должно работать и в C# работает именно так.
Очень жаль, но MQL за последние 10 лет так и не стал удобным средством программирования. Лучше бы у терминала было открытое API для возможности писать под него на любом удобном языке.
Спасибо за ответы. Тема закрыта.
Интересная особенность, но неочевидная и неудобная. В C# эта же функция работает по-другому, она читает все данные, которые пришли и возвращает кол-во прочитанных байт. К тому же позволяет указать смещение в буфере, по которому эти данные записывать.
buffer_maxlen - это максимальный размер буфера (у меня 100 байт), судя по имени, а не строгое количество байт, которое надо узнавать заранее у функции SocketIsReadable.
SocketIsReadable - булевская функция, судя по имени, которая просто показывает, что из сокета можно читать.
Это логично. Если в документации не так, то это очень плохо, потому как я полдня убил на то, что на первый взгляд должно работать и в C# работает именно так.
Очень жаль, но MQL за последние 10 лет так и не стал удобным средством программирования. Лучше бы у терминала было открытое API для возможности писать под него на любом удобном языке.
Спасибо за ответы. Тема закрыта.
Вы действовали по наитию, не удосужившись прочитать документацию, где четко сказано, что:
-
Возвращаемое значение у SocketIsReadable - количество байт, которые можно прочитать. В случае ошибки возвращает 0.
-
Параметр buffer_maxlen у SocketRead - количество байт, которые необходимо прочитать в массив buffer[]. Данные, которые не поместятся в массив, останутся в сокете. Их можно будет получить следующим вызовом SocketRead.
Дожили:
- программист не читает документацию (она обширнейшая, около 6000 страниц с примерами и разъяснениями)
- не видит ни статей, ни форума, где ему детально объясняют функционирование
- все равно считает свое видение главнее
Сразу отдавать пришедшие данные нельзя, так как TLS использует блочное декодирование вплоть до 16 кб на блок. Поэтому любая TLS реализация собирает сырые пакеты и только при возможности декодировки очередного пакета, начинает отдавать запрашивающему.
Если отдавать любой плавающий декодированный размер вместо запрошенного размера, то получится другая, даже еще более страшная проблема. Вам надо 10 байт, а вы вдруг получили 12 кб. Теперь вам нужно принимать нечеловеческие усилия для собственной буферизации и работы с этим буфером вместо прямого чтения из сокета.
С сетевыми операциями очень рекомендуется использовать четкий бинарный протокол с прямым указанием размеров. То есть, фреймовую структуру типа [size,type][...data...], чтобы на любом этапе четко знать сколько нужно читать. Для такого случая текущая реализация SocketTlsRead подходит хорошо.
А иначе остаются тормоза и неудобности нечетких протоколов типа текстового HTTP, где в реальности приходится вычитывать строку по одному символу или буферизированно/сложнее ради скорости.
Вы сами можете написать обходную функцию, которая посимвольно будет вычитывать весь доступный на текущий момент буфер. Реализация отдачи быстрая, так что особых тормозов от посимвольного чтения не будет.
В принципе, мы можем сделать возможность при указании нулевого размера выдавать весь доступный объем данных в функциях SocketRead и SocketTlsRead. Это будет гибко.
Кстати да, это будет отличное решение!
Прошу указать причину появления ошибки в примере ниже.
Функция SocketIsReadable возвращает значение 1292, и никакой ошибки не возникает:
Однако в дальнейшем функция SocketTlsReadAvailable возвращает -1, и возникает ошибка 5273:
Кстати, ошибка возникает только если последний параметр в SocketTlsReadAvailable включает первый символ с нулевым кодом в результате:

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Все проверки открытого соединения сюда писать не буду, для краткости. Скажу сразу, что сервер данные получает (отображает в интерфейсе) и отправляет ответ (16 байт). Но ответ советник не может прочитать.