powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TCP ReadBytes Indy10
47 сообщений из 47, показаны все 2 страниц
TCP ReadBytes Indy10
    #39845407
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые коллеги! Продолжая осваивать Indy, у меня возникла еще небольшая проблема... Как я писал в предпредыдущей теме, гоняю запросы через промежуточную службу по схеме Клиент-сужба(1)...служба(n)-служба(с обращением к web-сервису).
Для прогона запросов я решил использовать TCP-Client-Server, а также для пересылки кирилицы в кодировке utf-8 дабы не заморачиваться, принял совет использовать TBytes.
И вот вроде почти все огонь - запросы перенаправляются, ответы приходят, с кодировкой все в порядке, но как говорится есть нюанс. Если ответ на запрос небольшой, он приходит клиенту целиком, но если ответ становится большим (в ответе только xml), то почему-то при пересылке данные приходят не до конца. Чувствую, что это нубский вопрос, но ответ к сожалению я пока не нашел.
Отправляю данные вот так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
// Клиент
// Отправка запроса
IdTCPClient.Socket.Write(Buffer, -1, 0);
// Получение ответа
IdTCPClient.Socket.ReadBytes(Buffer, -1, False);

// На стороне сервера отправка ответа
AContext.Connection.Socket.Write(Buffer, -1, 0);



Проверял полноту ответа в районе службы - там все гуд. Потеря идет где-то именно при передаче данных.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845439
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13,

данные разбиваются и приходят по кусочкам, что бы отлавливать целые куски - нужно реализовывать пакеты, то есть передаваемые данные предварять например количеством передаваемых байтов
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845450
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13... почему-то при пересылке данные приходят не до конца
кто-то не до конца их вычитывает
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845477
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так как ты отказался от пересылки строк, то ты должен как-то контролировать, всё ли вычиталось и если нет, то читать дальше до конца.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845515
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наводящий вопрос: как клиенту понять, что все данные от сервера прочитаны?
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845548
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2Наводящий вопрос: как клиенту понять, что все данные от сервера прочитаны?

Передавать общую длину пакета. Или - маркировать пакеты сигнатурами.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845640
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде же параметр "-1" должен передавать/читать данные из сокета пока в буфере есть данные? Если не так, то получается надо сначала вычитать длину буфера через SizeOf(Buffer)?
Про сигнатуры я не знаю, но погуглю в эту сторону.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845642
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если с обеих сторон Read & Write вместо -1 написать Length(Buffer), сокет вываливается с ошибкой 10053. В логах службы пишется что запрос пришел к ней с нулевым размером. Тогда получается, что для Write надо использовать параметр -1, а для Read длину массива?
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845644
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А нее.. Я перепутал. Write делается с Length(Buffer), а Read с -1? Сейчас буду пробовать принимать большой пакет)))
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845646
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Неа, все равно не до конца прочитал
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845647
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрел длину уходящего и приходящего буфера. Уходящий =5510164, приходящий = 24464
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845651
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока еще не получается(((
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845653
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В нескоторых статьях пишется, что сначала отправляется размер, а потом считываются данные
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845720
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не в курсе про Инди, но есть подозрение, что этот ReadBytes работает как и recv сокета, а значит - читает только то, что есть в буфере сокета на данный момент. То есть цикл вычитки нужного количества данных ложится на программиста
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845733
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2,

да погоди ты, автор еще не сообразил что сокет из себя представляет
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845734
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2, правильно ли я понял, что тогда сначала мне надо послать от сервера клиенту длину массива, а потом в ReadBytes ее указать?
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845736
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений, ну я так понимаю, что по сокету запросы/ответы гоняются в виде пакетов возможно разной длины. Причем гоняются не сразу а через какой-то промежуток времени
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845744
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13,

на том уровне, на котором ты работаешь, нет ни запросов, нет ответов, нет пакетов, только последовательности байт, как их интерпретировать - задача которую тебе надо решить
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845750
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений, но если я в методе write указываю количество байт, почему клиент их принимает не весь?
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845752
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13Дегтярев Евгений, но если я в методе write указываю количество байт, почему клиент их принимает не весь?
Это ты указываешь на стороне отправщика сколько байт отправить.
Сторона приемщика их не получает и она не знает сколько надо получить. Это задача разработчика.

Как вариант посылаешь сначала всегда 4 байта - в них лежит размер следующего сообщения.
На сторне приемщика сначала принимаешь 4 байта, в них будет лежать сколько байт надо получить.
И пачками начинаешь получать ответ до тех пор, пока кол-во полученных байт не станет равно кол-ву переданного в начале.
Ну и полученные буферы надо клеить в один.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845756
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Примерный псевдокод на коленке

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Client.Write(100, 4); // значение 100 в 4 байта
Client.Write(Buffer, 100); // буфер размером в 100 байт


bs := TBytesStream.Create;
sz := Server.Read(4); // читаем 4 байта
repeat
  szreal := Server.Read(Buf, sz - bs.size); // пытаемся прочитать столько байт, сколько еще не приняли
  bs.Write(Buf, szreal);
until bs.size >= sz // если суммарно прочитано меньше чем надо - еще раз читаем
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845760
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Либо не изобретать велосипед с кубическими колесами и перейти на HTTP
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845762
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, с серверной стороны у меня там гуд. Это ответ клиенту длинный. ReadBytes это метод. Он ничего не возвращает. Ну то, что кусочками надо обрабатывать это я понимаю. Пока не могу сообразить как эти кусочки со стороны клиента обработать
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845763
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13X-Cite, с серверной стороны у меня там гуд. Это ответ клиенту длинный. ReadBytes это метод. Он ничего не возвращает. Ну то, что кусочками надо обрабатывать это я понимаю. Пока не могу сообразить как эти кусочки со стороны клиента обработать

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Server.Write(100, 4); // значение 100 в 4 байта
Server.Write(Buffer, 100); // буфер размером в 100 байт


bs := TBytesStream.Create;
sz := Client.Read(4); // читаем 4 байта
repeat
  szreal := Client.Read(Buf, sz - bs.size); // пытаемся прочитать столько байт, сколько еще не приняли
  bs.Write(Buf, szreal);
until bs.size >= sz // если суммарно прочитано меньше чем надо - еще раз читаем
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845764
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2Либо не изобретать велосипед с кубическими колесами и перейти на HTTP
на существующий rpc-like протокол, а что будет в качестве транспорта дело второстепенное
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845768
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, а на сервере не надо тогда отправку тоже в цикл заворачивать, если мы кусочками по 100 байт шлем?
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845771
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
100 байт - это пример. В данном случае все сообщение....
Можно и 100 Мб отправить одним Write
Кусочками только принимаем...
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845772
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, Получается вместо 100 на сервере я указываю свою длину массива байтов. Читаю ее клиентом и в цикле складываю его по кусочкам?
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845774
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13,
Я думаю в indy есть метод типа Client.ReadAll(Buf, sz); который будет ждать и читать сам внутри до тех пор пока не получит размер sz
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845775
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тогда код на клиенте свернется до
Код: pascal
1.
2.
sz := Client.Read(4);
Client.ReadAll(Buf, sz);



Кстати на сервере надо делать также...
Где гарантия что переданные вами 10 байт, по дороге не разобьются на 2 части и не придут двумя сообщениями в 4 и 6 байт...
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845777
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, ну да согласен. Сейчас будем копать...
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845784
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, попробовал сделать так:
Сервер:
Код: pascal
1.
2.
Acontext.Connections.Socket.Write(Length(Buffer), True); // Передает размер
Acontext.Connection.Socket.Write(Buffer, Length(Buffer), 0);



Клиент:
Код: pascal
1.
2.
sz := IdTCPClient.Socket.ReadInt64();
IdTcpClient.Socket.ReadBytes(Buffer, sz, False);



Сваливается в Connection Closed Gracefully. В Буфере на сервере 3653 длина, а в sz приходит аж 1010792557... Чет то много
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845788
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Socket.Write(Length(Buffer), True); - сколько байт вы передаете здесь.
IdTCPClient.Socket.ReadInt64(); - столько байт надо читать здесь.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845793
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, здесь нельзя указать количество байт
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845796
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев ЕвгенийВасилий 2Либо не изобретать велосипед с кубическими колесами и перейти на HTTP
на существующий rpc-like протокол, а что будет в качестве транспорта дело второстепенное
Не совсем. В HTTP есть уже все приколы с длиной ответа, поточность, если вдруг понадобится, стандартизация. Учитывая уровень знаний ТС, намного легче взять уже готовое и на его основе с небольшими доработками сваять нужный функционал
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845797
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2, да как то осталась только часть с получением ответа. Не хотелось бы из-за этого полностью менять подход.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845804
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот вопрос решился. Немного надо будет конечно обработать всякие исключения, но получилось примерно так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
// Сервер
Socket.WriteLn(IntToStr(Length(Buffer))) // отправляем размер буфера
Socket.Write(Buffer, Length(Buffer), 0); // отправляем сам буфер

// На клиенте
sz := StrToInt(Socket.Readln()); // получили размер
Socket.ReadBytes(Buffer, sz, false) // получили буфер

// дальше его обработка



Спасибо всем за участе. Отдельное спасибо XCite
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845817
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно учитывать, что метод Readln не выбрасывает исключение при ошибке таймаута, а возвращает пустую строку (хотя возможно разное поведение в разных версиях Indy10).
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845820
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Также нежелательно передавать большой объём данных одним блоком. Должно быть ограничение, например максимум 5 МБ. При приёме также желательно контролировать объём данных, принимаемых с клиента и если InputSize больше 5 МБ, то это может быть атакой на сервер из чужого ПО, в этом случае дочитываем буфер и рвём связь.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845822
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer, там не такие большие пакетики. В них XML-на.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845826
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13
Код: pascal
1.
2.
3.
Socket.WriteLn(IntToStr(Length(Buffer))) // отправляем размер буфера

sz := StrToInt(Socket.Readln()); // получили размер



все будет хорошо
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845912
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений, ну это ответ на коленке. В реалии я конечно же оборачиваю все это дело в проверки и try
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845959
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если бы ты пересылал строки, то инди бы само разбиралось с передачей. Ну а массивы байт придётся дополнительно обрабатывать
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39845964
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13,

if string(flag) == "true"
вспомнилось
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39846021
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dartveider13X-Cite, здесь нельзя указать количество байт

Код: pascal
1.
2.
3.
Socket.Write(Int32(Length(Buffer))); // передаем 4 байта т.к. есть метод procedure Write(AValue: Int32; AConvert: Boolean = True); overload;

sz := IdTCPClient1.Socket.ReadInt32() // читаем 4 байта



ну или так тоже можно
Код: pascal
1.
2.
Socket.Write(ToBytes(Length(Bytes)), 4); // передаем 4 байта
sz := Socket.ReadInt32() // читаем 4 байта


А то какие-то извращения со строками.
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39847277
dartveider13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, о спасибо. Действительно извращение со строками
...
Рейтинг: 0 / 0
TCP ReadBytes Indy10
    #39847280
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да неужели
...
Рейтинг: 0 / 0
47 сообщений из 47, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TCP ReadBytes Indy10
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]