Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Уважаемые коллеги! Продолжая осваивать Indy, у меня возникла еще небольшая проблема... Как я писал в предпредыдущей теме, гоняю запросы через промежуточную службу по схеме Клиент-сужба(1)...служба(n)-служба(с обращением к web-сервису).
Для прогона запросов я решил использовать TCP-Client-Server, а также для пересылки кирилицы в кодировке utf-8 дабы не заморачиваться, принял совет использовать TBytes.
И вот вроде почти все огонь - запросы перенаправляются, ответы приходят, с кодировкой все в порядке, но как говорится есть нюанс. Если ответ на запрос небольшой, он приходит клиенту целиком, но если ответ становится большим (в ответе только xml), то почему-то при пересылке данные приходят не до конца. Чувствую, что это нубский вопрос, но ответ к сожалению я пока не нашел.
Отправляю данные вот так:
// Клиент
// Отправка запроса
IdTCPClient.Socket.Write(Buffer, -1, 0);
// Получение ответа
IdTCPClient.Socket.ReadBytes(Buffer, -1, False);

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


Проверял полноту ответа в районе службы - там все гуд. Потеря идет где-то именно при передаче данных.
5 авг 19, 14:47    [21942111]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Zelius
Member

Откуда: Россия, Москва
Сообщений: 1375
dartveider13,

данные разбиваются и приходят по кусочкам, что бы отлавливать целые куски - нужно реализовывать пакеты, то есть передаваемые данные предварять например количеством передаваемых байтов
5 авг 19, 15:46    [21942180]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Дегтярев Евгений
Member

Откуда: Барнаул
Сообщений: 1708
dartveider13
... почему-то при пересылке данные приходят не до конца

кто-то не до конца их вычитывает
5 авг 19, 16:00    [21942195]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3401
Так как ты отказался от пересылки строк, то ты должен как-то контролировать, всё ли вычиталось и если нет, то читать дальше до конца.
5 авг 19, 17:06    [21942255]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Василий 2
Member

Откуда:
Сообщений: 801
Наводящий вопрос: как клиенту понять, что все данные от сервера прочитаны?
5 авг 19, 17:42    [21942316]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
DarkMaster
Member

Откуда: Donetsk,Ukraine
Сообщений: 6241
Василий 2
Наводящий вопрос: как клиенту понять, что все данные от сервера прочитаны?


Передавать общую длину пакета. Или - маркировать пакеты сигнатурами.
5 авг 19, 18:59    [21942384]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Вроде же параметр "-1" должен передавать/читать данные из сокета пока в буфере есть данные? Если не так, то получается надо сначала вычитать длину буфера через SizeOf(Buffer)?
Про сигнатуры я не знаю, но погуглю в эту сторону.
6 авг 19, 05:28    [21942561]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Если с обеих сторон Read & Write вместо -1 написать Length(Buffer), сокет вываливается с ошибкой 10053. В логах службы пишется что запрос пришел к ней с нулевым размером. Тогда получается, что для Write надо использовать параметр -1, а для Read длину массива?
6 авг 19, 06:01    [21942563]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
А нее.. Я перепутал. Write делается с Length(Buffer), а Read с -1? Сейчас буду пробовать принимать большой пакет)))
6 авг 19, 06:13    [21942565]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Неа, все равно не до конца прочитал
6 авг 19, 06:27    [21942567]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Посмотрел длину уходящего и приходящего буфера. Уходящий =5510164, приходящий = 24464
6 авг 19, 06:37    [21942569]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Пока еще не получается(((
6 авг 19, 07:54    [21942578]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
В нескоторых статьях пишется, что сначала отправляется размер, а потом считываются данные
6 авг 19, 08:14    [21942580]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Василий 2
Member

Откуда:
Сообщений: 801
Не в курсе про Инди, но есть подозрение, что этот ReadBytes работает как и recv сокета, а значит - читает только то, что есть в буфере сокета на данный момент. То есть цикл вычитки нужного количества данных ложится на программиста
6 авг 19, 10:36    [21942672]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Дегтярев Евгений
Member

Откуда: Барнаул
Сообщений: 1708
Василий 2,

да погоди ты, автор еще не сообразил что сокет из себя представляет
6 авг 19, 10:50    [21942685]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Василий 2, правильно ли я понял, что тогда сначала мне надо послать от сервера клиенту длину массива, а потом в ReadBytes ее указать?
6 авг 19, 10:50    [21942686]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Дегтярев Евгений, ну я так понимаю, что по сокету запросы/ответы гоняются в виде пакетов возможно разной длины. Причем гоняются не сразу а через какой-то промежуток времени
6 авг 19, 10:52    [21942688]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Дегтярев Евгений
Member

Откуда: Барнаул
Сообщений: 1708
dartveider13,

на том уровне, на котором ты работаешь, нет ни запросов, нет ответов, нет пакетов, только последовательности байт, как их интерпретировать - задача которую тебе надо решить
6 авг 19, 11:00    [21942697]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
Дегтярев Евгений, но если я в методе write указываю количество байт, почему клиент их принимает не весь?
6 авг 19, 11:06    [21942704]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1604
dartveider13
Дегтярев Евгений, но если я в методе write указываю количество байт, почему клиент их принимает не весь?

Это ты указываешь на стороне отправщика сколько байт отправить.
Сторона приемщика их не получает и она не знает сколько надо получить. Это задача разработчика.

Как вариант посылаешь сначала всегда 4 байта - в них лежит размер следующего сообщения.
На сторне приемщика сначала принимаешь 4 байта, в них будет лежать сколько байт надо получить.
И пачками начинаешь получать ответ до тех пор, пока кол-во полученных байт не станет равно кол-ву переданного в начале.
Ну и полученные буферы надо клеить в один.
6 авг 19, 11:10    [21942707]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1604
Примерный псевдокод на коленке

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 // если суммарно прочитано меньше чем надо - еще раз читаем
6 авг 19, 11:18    [21942714]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Василий 2
Member

Откуда:
Сообщений: 801
Либо не изобретать велосипед с кубическими колесами и перейти на HTTP
6 авг 19, 11:23    [21942720]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
dartveider13
Member

Откуда: Омск
Сообщений: 707
X-Cite, с серверной стороны у меня там гуд. Это ответ клиенту длинный. ReadBytes это метод. Он ничего не возвращает. Ну то, что кусочками надо обрабатывать это я понимаю. Пока не могу сообразить как эти кусочки со стороны клиента обработать
6 авг 19, 11:26    [21942726]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1604
dartveider13
X-Cite, с серверной стороны у меня там гуд. Это ответ клиенту длинный. ReadBytes это метод. Он ничего не возвращает. Ну то, что кусочками надо обрабатывать это я понимаю. Пока не могу сообразить как эти кусочки со стороны клиента обработать


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 // если суммарно прочитано меньше чем надо - еще раз читаем
6 авг 19, 11:29    [21942732]     Ответить | Цитировать Сообщить модератору
 Re: TCP ReadBytes Indy10  [new]
Дегтярев Евгений
Member

Откуда: Барнаул
Сообщений: 1708
Василий 2
Либо не изобретать велосипед с кубическими колесами и перейти на HTTP

на существующий rpc-like протокол, а что будет в качестве транспорта дело второстепенное
6 авг 19, 11:30    [21942733]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить