Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.02 c
2-1166476180
boleg
2006-12-19 00:09
2007.01.07
Про двойной клик


9-1141459817
NightLord
2006-03-04 11:10
2007.01.07
PlugInIntf из GLScene


2-1165919107
koha
2006-12-12 13:25
2007.01.07
Удаление строки в ADOQuery через SQL - Немогу удалить


1-1163765000
laronov
2006-11-17 15:03
2007.01.07
выделение в ComboBox


3-1161369447
alex_sz
2006-10-20 22:37
2007.01.07
Размер базы *.gdb





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский