Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.07;
Скачать: CL | DM;

Вниз

O пересылке данных с TIdTCPServer   Найти похожие ветки 

 
DanilinS   (2006-07-25 15:15) [0]

Необходимо дергать данные с сервера. Данные структурированы но их обьем заренее не известен.

Не могу понять, почему не работает следующий код:

Сервер:

код:
procedure TForm1.CommandServerException(AThread: TIdPeerThread;
 AException: Exception);
var
 TempStrings: TStrings;
 I:Byte;
begin
 AThread.Connection.ReadBuffer(CommandS, SizeOf(CommandS));
 case CommandS.Command of
   01: begin  // старт динамического импорта

      ...
       end;
   02: begin     // Стоп динамического импорта
          ...
       end;
   03: begin     // Запрос перечня данных
         if PathBase = "" then Exit;
         if PathBase[Length( PathBase )] <> "\" then
           PathBase := PathBase + "\";
         FillSymbols(PathBase);  // загнали данные в массив
         TempStrings:=TStringList.Create;
         For i:=0 to Length (ArrayMasterRec) do
           TempStrings.Add(ArrayMasterRec[i].Name);
         Label3.Caption:= ArrayMasterRec[0].Name;
         AThread.Connection.WriteStrings(TempStrings); // кинули данные
         TempStrings.Free;
       end;
   04: begin   // Запрос исторических данных
          ...
       end;
 end;
end;


клиент:
код:
procedure TForm1.Button3Click(Sender: TObject);
var
 TempList: Tstrings;
 Int: integer;
 S: string;
begin
 TempList := TStringList.Create;
 CommandS.Command:=3;
 IdTCPClient1.Connect(-1);
 IdTCPClient1.WriteBuffer(CommandS, SizeOf(CommandS));
 Int:=IdTCPClient1.ReadInteger(true);
 IdTCPClient1.ReadStrings(TempList);  <- получаю "Connection Closed Gracefully"
 Memo1.Lines.AddStrings(TempList);
 IdTCPClient1.Disconnect;
 TempList.Free;
end;


Кто подскажет, как TString через сетку протащить?


 
Reindeer Moss Eater ©   (2006-07-25 15:27) [1]

При чем здесь обработчик CommandServerException?
Что такое CommandS?


 
DanilinS   (2006-07-25 15:51) [2]

Сорри ... опечатка. CommandServerExecute естественно

CommandS: TCommand;

TCommand = record
   Command: Byte;
   Name: String [20];
end;


 
umbra ©   (2006-07-25 15:51) [3]


> CommandServerException

А почему обработку команд Вы вешаете на обработчик исключений, возникающих в потоке, работающем с клиентом?


 
umbra ©   (2006-07-25 16:00) [4]

а как согласуется
case CommandS.Command of
  01: begin  // старт динамического импорта

     ...
      end;


с

TCommand = record
  Command: Byte;
  Name: String [20];
end;


 
Reindeer Moss Eater ©   (2006-07-25 16:08) [5]

>Сорри ... опечатка. CommandServerExecute естественно

Мы здесь реальный код рассматриваем или опечатки?

Не могу понять, почему не работает следующий код:
Потому что у тебя нет этого кода.


 
DanilinS   (2006-07-25 16:34) [6]

При переносе случайно затер часть строки ... и набил бегом ручками. Что-бы не раздувать тему приходиться часть кода, не относящегося к делу затирать. А что-то забывать затирать. Например строку Int:=IdTCPClient1.ReadInteger(true) в клиенте ... А что почту свою не поставил? Код уже лежал-бы у тебя ....

А что с case не так ? Читаем запись и используем поле с типом byte в case ... 100% рабочий код. Case рабочий.

Непонятно, почему в клиенте при IdTCPClient1.ReadStrings(TempList) получаю ошибку типа "Connection Closed Gracefully" ?


 
Reindeer Moss Eater ©   (2006-07-25 16:37) [7]

Получаешь, потому что соединение закрылось.


 
DanilinS   (2006-07-25 16:48) [8]

Оно (соединение ) почему закрылось? Я его ручками не закрывал .... Или отработал блок CommandServerExecute и оно автоматом закрылось, без команды клиента? А как тогда ему подождать, пока клиент данные заберет?

А куда данные делись, которые сервер командой WriteStrings отправил? В клиенте комманда ReadStrings их не получила ... Кроме ошибки ес-но ....


 
Reindeer Moss Eater ©   (2006-07-25 17:40) [9]

Оно (соединение ) почему закрылось? Я его ручками не закрывал ....

У тебя в кейсе для 03 столько потенциально опасного кода, вызывающего AV, что ручками закрывать и не надо.


 
DanilinS   (2006-07-26 10:49) [10]


> У тебя в кейсе для 03 столько потенциально опасного кода,
>  вызывающего AV, что ручками закрывать и не надо.

Согласен. Потом причешу. Ко кейс рабочий. Завёл Memo и писал логи в него. Кейс отрабатывал штатно без ошибок.

Похоже немного понимаю в чём трабла. Если заменить IdTCPClient1.ReadStrings(TempList) на IdTCPClient1.ReadStrings(TempList,15) то всё работает. Правда читает только первые 15 записей.

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


 
umbra ©   (2006-07-26 11:06) [11]


> Судя по всему ReadStrings не понимает количество строчек

прочтите справку по ReadStrings


 
Сергей М. ©   (2006-07-26 11:08) [12]


> ReadStrings не понимает количество строчек


Долден "понимать", если в ReadStrings и в соответствующем WriteStrings второй параметр умалчивается.


 
Reindeer Moss Eater ©   (2006-07-26 11:23) [13]

Так и у автора он понимает. Просто сам автор не понимает что такое "Connection Closed Gracefully" .


 
DanilinS   (2006-07-26 11:39) [14]

Похоже нефига не "понимает". Но у WriteStrings есть второй необязательный параметр "const AWriteLinesCount: Boolean = False"

Не он-ли заведует передачей данных о кол-ве записей? По умолчанию он выключен ....


 
Сергей М. ©   (2006-07-26 11:53) [15]


> Не он-ли заведует передачей данных о кол-ве записей? По
> умолчанию он выключен


Да, именно он и заведует.
Если ты умолчал этот параметр или если явно прописал false, то внутри метода WriteStrings в выходной поток сначала (1) будет записано Integer-значение, равное кол-ву строк, а следом (2) сами строки, в противном случае шаг (1) не выполняется - сразу же выполняется шаг (2).

Тоже самое касается и ReadString - умолчание 2-го параметра или явное его указание (-1) заставляет ожидать/читать из вх.потока сначала Integer-значение, равное кол-ву непосредственно следующих строк.


 
DanilinS   (2006-07-26 11:53) [16]

В общем ситуация такова: ReadStrings ждет до бесконечности в готовности принять практически любой обьем данных и обижаеться ошибкой Connection Closed Gracefully на закрытие сервером соединения. Но если WriteStrings (..., true) то сначало посылаеться переменная Integer, которая указывает кол-во записей. Далее на стороне клиента

I:=IdTCPClient1.ReadInteger();
 IdTCPClient1.ReadStrings(TempList, I);


 
DanilinS   (2006-07-26 11:58) [17]

Уточнение:
> Если ты умолчал этот параметр или если явно прописал false,
>  то внутри метода WriteStrings в выходной поток сначала
> (1) будет записано Integer-значение, равное кол-ву строк,
>  а следом (2) сами строки,


Не перепутал? при умолчании или false Integer-значение не пишеться

У меня по крайней мере ...


 
Сергей М. ©   (2006-07-26 11:59) [18]

Логика вызова ReadStrings(TempList) полностью эквивалентна приведенной тобой логике, нет смысла вызывать сначала ReadInteger(), а затем ReadStrings(TempList, I) - ReadStrings(TempList) делает все тоже самое, но неявно.


 
Сергей М. ©   (2006-07-26 12:02) [19]


> Не перепутал?


Да, перепутал.

Конечно же, все наоборот - Count записывается строго при явном указании True.


 
DanilinS   (2006-07-26 12:17) [20]

Ок. Приведенное выше проверено и работает. Спасибо всем, что помогли разобраться.


 
Сергей М. ©   (2006-07-26 12:23) [21]

В условиях глоб.сети твой код может споткнуться еще об одни грабли.
Посмотри внимательно на ф-цию Get/SetSockOpt и опции SO_LINGER/SO_DONTLINGER.


 
DanilinS   (2006-08-11 15:35) [22]

В догонку вопрос:
Если на стороне сервера (TIdTCPServer) используеться функция AThread.Connection.WriteFile
то какой функцией TIdTCPClient эти данные можно принять "оптом" (не по байтно)?

функцией IdTCPClient1.ReadStream ? Какой Stream нужно в этом случае использовать? (TMemoryStream ?)


 
Сергей М. ©   (2006-08-11 15:41) [23]


> Какой Stream нужно в этом случае использовать? (TMemoryStream
> ?)


Любой наследник TStream



Страницы: 1 вся ветка

Текущий архив: 2007.01.07;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.059 c
15-1166473407
std112
2006-12-18 23:23
2007.01.07
Microsoft Visual Studio .NET VC7


15-1166076363
Tab
2006-12-14 09:06
2007.01.07
RX Library


15-1166202787
furyz
2006-12-15 20:13
2007.01.07
Linux Cs 1.6 server


2-1166447443
Slimer
2006-12-18 16:10
2007.01.07
Прога с парадокс на чистом ХР


15-1166451602
Ega23
2006-12-18 17:20
2007.01.07
Директивы условной компилляции "извне"