Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Глупый вопрос по TTCPClient [D7, Win2k]


Страницы:   1 2

alt7 ©   (2003-10-21 14:26:00) 

Не могу понять вот какой вещи.

С помощью данного компонента коннекчусь к серверу, прохожу авторизацию и подписываюсь на определенные порции данных, пользуюсь методами ReceiveLn, SendLn, SendBuf. Это все в отдельной процедуре.

Затем эти данные ничанают сыпаться моему клиенту, НО обработчик TTCPClient.OnReceive не срабатывает, когда они приходят, почему?

Обходной путь, сделал таймер который срабатывает 10 раз в секунду, а в нем вызываю ReceiveLn для компонента, но это грузит процессор на все 100% и не подходит мне.

Главные вопросы: почему не срабатывает событие OnReceive, и что сделать, чтобы срабатывало без вышеупомянутого таймера?


alt7   (2003-10-21 17:48:00) [21]

Порезал немного для краткости. Команда STAR - сервер начинает отсылать данные.


procedure EventClass.Before_get_quote;
var
zz: Integer;
USR,REQU,START: String;
REQU_arr: Array[1..9] of String;
begin
USR := <skipped>;
REQU := <skipped>
<skipped заполненние массива REQU>

while true do
try
if Form_CTD.TCPCClient.WaitForData(10) then break;
except on ESocketError do begin WriteLn(vLogFile,"Connection error. Trying to reconnect... ("+DateTimeToStr(Now)+")"); Before_get_quote; exit; end; end;
Buffer := Form_CTD.TCPCClient.Receiveln;
if Pos(cOKString,Buffer) <> 0 then
begin
Form_CTD.TCPCClient.Sendln(USR);
end;
while true do
try
if Form_CTD.TCPCClient.WaitForData(10) then break;
except on ESocketError do begin WriteLn(vLogFile,"Connection error. Trying to reconnect... ("+DateTimeToStr(Now)+")"); Before_get_quote; exit; end; end;
Buffer := Form_CTD.TCPCClient.Receiveln;
if Pos("OK User logged ",Buffer) <> 0 then
begin
for zz := 1 to Length(REQU) do
begin
SendChar := REQU[zz];
Form_CTD.TCPCClient.SendBuf(SendChar,1,0);
end;
Form_CTD.TCPCClient.SendLn("");
for zz := 1 to Length(REQU_arr[1]) do
begin
SendChar := REQU_arr[1][zz];
Form_CTD.TCPCClient.SendBuf(SendChar,1,0);
end;
Form_CTD.TCPCClient.SendLn("");
<skipped однотипно>
end;

while true do
try
if Form_CTD.TCPCClient.WaitForData(10) then break;
except on ESocketError do begin WriteLn(vLogFile,"Connection error. Trying to reconnect... ("+DateTimeToStr(Now)+")"); Before_get_quote; exit; end; end;
Buffer := Form_CTD.TCPCClient.Receiveln;
if (Pos("OK",Buffer) <> 0) and (Length(Buffer) = 2) then
begin
for zz := 1 to Length(STAR) do
Form_CTD.TCPCClient.SendBuf(STAR[zz],1,0);
Form_CTD.TCPCClient.SendLn("");
end;
end;


Далее сервер мне сыпет данные, которые я должен обрабатывать.
Мои вопросы по этому делу можно прочитать выше...


Rouse_   (2003-10-21 17:35:00) [22]

Без кода вы опускаетесь до бесполезного флейма и разговариваете о разных вещах.

> alt7
Покажи свой код, и тебе скажут где ошибка
(ну это помимо ошибки в 17-ой строке наличествующей сейчас).

Желаю успехов


alt7   (2003-10-21 17:33:00) [23]

1) Размер буфера, а точнее количество байтов я зараннее не знаю, можно ли указать какое-нить большое число, и чтоб не было ошибки?

2)
> Вызовешь метод чтения строки, получишь от сервера строку
> - и снова вызывай метод чтения строки


И где вызывать этот метод? Учитывай же, что мне придется постоянно его вызывать, потому как время поступления мне критически важно.


Reindeer Moss Eater   (2003-10-21 17:28:00) [24]

Тут тоже никакого волшебства нет.
Вызовешь метод чтения строки, получишь от сервера строку - и снова вызывай метод чтения строки (строка для примера).
Либо один раз метод чтения буфера длинны N.
Обрабатывай буфер (ищи разделители строк) и отображай результат


alt7   (2003-10-21 17:22:00) [25]

Так ведь ты же пишешь, что для того чтобы что-то получить клиентом нужно вызвать соответствующий метод класса, к примеру ReceiveLn. а если мне ПОСТОЯННО надо что-то читать от телнет-сервера, и нет никакой переодичности в поступлении сообщений, мне же приходится постоянно вызывать ReceiveLn или же делать проверку WaitForData с таймаутом, чтобы узнать, что что-то пришло. Но вся шутка в том что ПОСТОЯННО, постоянно я придумал только по таймеру, и получается что грузим проц на 100%. Вот как бы обойти это дело...


Reindeer Moss Eater   (2003-10-21 16:41:00) [26]

А я ведь не пишу каждую минуту, час, месяц - ReceiveLn, я просто сижу, а они сыпятся.

А какая связь между " ЯНИЧЕГО НЕ ПИШУ ТЕЛНЕТ СЕРВЕРУ" и "Телнет клиент читает сообщения которые пишет телнет-сервер" ?


alt7   (2003-10-21 16:38:00) [27]

Здесь все понятно, спасибо за разъяснение ;))

Зайдем с другого конца:
Коннекчусь я телнетом к тому же серваку, подписываюсь на данные, даю команду серваку, и он мне начинает сыпать данные, хоть минуту, хоть час, хоть месяц...
А я ведь не пишу каждую минуту, час, месяц - ReceiveLn, я просто сижу, а они сыпятся.

Так вот мне такое и на Делфи сделать, чтобы я дал команду, а сервер мне хоть месяц все сыпал и сыпал без каких-либо моих команд в течении этого месяца.


Reindeer Moss Eater   (2003-10-21 16:31:00) [28]

при поступлении данных срабатывает некоторое событие (без вызова ReceiveLn)

Ты думаешь, что событие в каком-то классе - это результат активности сервера на другом конце?
Это всего навсего код создателя класса который внутри класса читает данные (а делает он это потому что пользователь класса вызвал метод класса заставляющий класс выполнить чтение даных).

Иными словами, что бы иметь события - необхродимо вызывать методы.


alt7   (2003-10-21 16:26:00) [29]

Хорошо, тогда подсоби все же если можешь с решением вопроса:

Если не TTCPClient, то в каком классе можно так: при поступлении данных срабатывает некоторое событие (без вызова ReceiveLn) и в его обработчике я уже буду писать свой код.

Если такого нельзя, то куда и как поместить вызов ReceiveLn, чтобы не грузить процессор на 100%?


Reindeer Moss Eater   (2003-10-21 16:16:00) [30]

Ну вот видишь меня так не устраивает, данные получаю критичные, секунда имеет огромную важность.

1. Синхронный режим этому никак не мешает.
2. Мы про разные классы разговаривали. Так что забудь.


alt7   (2003-10-21 16:13:00) [31]

1) Ну вот видишь меня так не устраивает, данные получаю критичные, секунда имеет огромную важность.
Посему такой вопрос, куда и как можно впихнуть ReceiveLn (я правильно тебя понял?) чтобы обработать новую порцию данных? И чтобы при этом не грузить проц на 100%.

2) Deplhi 7, выдержка из Help

TTcpClient is the TCP client component

Unit

Sockets

Description

Use TTcpClient to create TCP client applications.

TTcpClient publishes properties and events from its ancestor socket components.


Reindeer Moss Eater   (2003-10-21 16:07:00) [32]

Кстати, что такое TTCPClient?


Reindeer Moss Eater   (2003-10-21 16:00:00) [33]

Я про сервер ни слова не сказал.
Я сказал, что для получения данных нужно вызвать метод.
Как только произойдет возврат из метода - данные пришли или случился таймаут.


alt7   (2003-10-21 15:57:00) [34]

Гм, то есть ты хочешь сказать, что пока я не сделаю ReceiveLn, то сервер мне ничего не ответит? А мне ведь надо, чтобы я один раз подписался на нужные данные, а сервер по мере появления данных у него, отсылал мне эти данные постоянно, пока я законнекчен... (не очень сумбурно? ;)))

То есть именно нужен обработчик, который постоянно бы мог обрабатывать поступающую инфо без всяких ReceiveLn, SendLn...

Если этого не может TTCPClient, то чем можно такое сделать?


Reindeer Moss Eater   (2003-10-21 15:45:00) [35]

Главные ответы:
Событий никаких не нужно, так же как и таймера.
Все методы синхронные вызвал - получил по возврату из вызова


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо