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

Вниз

Indy....   Найти похожие ветки 

 
$hade   (2002-01-21 14:22) [0]

Народ! Я глючу или где?...
Есть сервер на TIdTCPServer (стандартный в D6)...Клиент соответственно TIdTCPClient....
Мне нужно получать сообщения от сервера...причем типа record.Для этого использую WriteBuffer/ReadBuffer...Вроде все нормально...Но так как у клиента нет события на пришедшее сообщение(или я плохо искал?)...приходится читать по таймеру... И тут косяк : Если буффер пустой (а проверить я это тоже не могу) то все виснет...Как это лечить?


 
Digitman   (2002-01-21 14:57) [1]

Не может быть, чтобы класс TIdTCPClient не реализовал событие OnRead() ! И чтение буфера приема корректней всего выполнять в обработчике именно данного события (и неважно, Indy там или еще чего - суть работы синхронного режима гнезда одна и таже и не меняется ни в Indy ни где-то там еще : Winsock остается Winsock"ом). Если же ты читаешь буфер приема асинхронно (например, по таймеру), то возникающие ошибки - это только твои ошибки, а не Indy. Потому что чтение буфера приема гнезда, в принципе, допустимо в любом месте кода (при условии, что гнездо создано , инициализировано и соединено с гнездом-партнером по коннекту).
Приводи код - разберемся


 
$hade   (2002-01-21 15:37) [2]

Ну нету там OnRead...нету! Есть OnStatus...вроде как возвращает состояние Read или Write...но опять же или я не разобрался или не работает...
а код...
OnTimer
if Client.connected then
if Client.CurrentReadBufferSize<>0 then
s:=Client.ReadString;// это чтение строки...примерно так..работает...
а вот так:
Client.ReadBuffer(Buff,SizeOf(Buff));

не работает - CurrentReadBufferSize всегда равен 0!
а если не делать проверку на размер...Client пытается прочитать буффер даже если там ничего нету...то есть сервер не отправлял ничего...((




 
nikkie   (2002-01-21 15:42) [3]

зачем таймер? просто делаешь ReadBuffer (имхо CurrentReadBufferSize проверять не надо). Indy - блокирующие сокеты. если надо, чтобы приложение не подвисало - либо кидаешь на форму IdAntiFreeze, либо работаешь в отдельном потоке.


 
$hade   (2002-01-21 15:53) [4]

Так а где его делать тогда (ReadBuffer) если не в таймере? как я узнаю что сообщение пришло?
...вот как раз когда не используешь CurrentReadBufferSize приложение и виснет...то есть как я понял пока он не прочитает SizeOf(Buff) он не успокоится...а прочитать не может потому что буффер пустой...((


 
Digitman   (2002-01-21 16:12) [5]

а, ну , если Indy-клиент - блокирующий, тогда, разумеется, ввод-вывод синхронный д.б. (событий вв/выв гнезда в привычном VCL-виде там не будет)


 
nikkie   (2002-01-21 16:53) [6]

ReadBuffer возвратит управление, когда придет столько данных, сколько ты просишь. какие проблемы?

виснет - не проблема. есть компонента AntiFreeze.


 
$hade   (2002-01-22 08:29) [7]

все правильно...все работает...НО...КАК ОПРЕДЕЛИТЬ ЧТО ПРИШЛО СООБЩЕНИЕ??


 
$hade   (2002-01-22 08:32) [8]

впрочем...мож кто подскажет какой-нить другой компонент в котором есть события OnRead/OnWrite + поддержка Proxy + SSL ?


 
Digitman   (2002-01-22 08:48) [9]

var
FDSet: TFDSet;
TimeVal: TTimeVal;
BytesToRead: Longint;
...

FD_ZERO(FDSet);
FD_SET(IdTCPClient.SocketHandle, FDSet);
TimeVal.tv_sec := 0;
TimeVal.tv_usec := 500;
if (select(0, @FDSet, nil, nil, @TimeVal) > 0) then //FD_READ ?
begin
ioctlsocket(IdTCPClient.SocketHandle, FIONREAD, BytesToRead); // буфер чтения не пуст ?
if BytesToRead > 0 then
.... IdTCPClient.ReadBuffer(.., BytesToRead, ...); // можно читать не более BytesToRead байт
end;

единственное, в чем не уверен, это - наличие у IdTCPClient св-ва SocketHandle. Оно может и по-другому называться, но суть от этого не меняется : зная хэндл кл.гнезда, можно вот таким образом корректно обратиться к нему для чтения вх.буфера


 
nikkie   (2002-01-22 09:54) [10]

>КАК ОПРЕДЕЛИТЬ ЧТО ПРИШЛО СООБЩЕНИЕ??
сработал оператор после ReadBuffer.

>другой компонент в котором есть события OnRead/OnWrite + поддержка Proxy + SSL ?
ты видно не понимаешь всей прелести. тебе НЕ НУЖНЫ эти события. событийное программирование сокетов - микрософтовская придумка. люди уже три десятка лет пишут сетевые программы без этих событий - и ничего.

почитай статью здесь:
http://www.hower.org/Kudzu/Articles/IntroToIndy/
может, понятней станет логика.

в indy есть поддержка SSL, есть поддержка socks. насколько я знаю, поддержки http-прокси нет, но ее можно сделать и самому, это должно быть не сложно - смотри RFC1945


 
$hade   (2002-01-22 10:06) [11]

2nikkie ©
Thanks...обязательно почитаю...
но все-таки...вообще пишу чат( chat+InstantMessanger(ICQ)+IRC...вощем гибрид вcего :))..
надо как-то соображать что пришло сообщение/команда...(передается не только текст но и другие данные вплоть до картинки(баннер)-потому и передаю не текст а record)...
и не ждать когда наконец то прийдет сообщение от сервера чтоб отправить свое...


 
nikkie   (2002-01-22 10:17) [12]

у тебя программа же не зависает? значит сообщения обрабатываются. значит и OnButtonClick сработает. там ты и делаешь отправку сообщения.

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


 
$hade   (2002-01-22 12:26) [13]

ну да...в принципе не зависает...потому как перерефрешивается...и все...не сдвинуть...не открыть/закрыть...:))
а потоки...можно конечно...но по моему это изврат...проще должно быть...))


 
nikkie   (2002-01-22 12:57) [14]

блин... я действительно так непонятно объясняю? прочитай тогда статью.

компонента IdAntiFreeze с закладки Indy Misc.

а потоки - это вполне логичная вещь.


 
$hade   (2002-01-22 13:57) [15]

2nikkie ©
да нет...все понятно...:) наверное я сам не непонятно выражаюсь... про AntiFreeze я знаю...
да ...наверное всетаки с потоками придется делать...)

Thanks 2All!


 
nikkie   (2002-01-22 14:28) [16]

странно. а у тебя какая версия инди и дельфи? у меня дежа вю - вроде кто-то жаловался, что ReadBuffer вешает программу даже с антифризом. у меня D5 + Indy 8.00.23

смотри делаю так: новый апп, на форму кладу IdTCPClient, Host = "www.ya.ry", Port = 80.

кладу кнопку.

procedure TForm1.Button3Click(Sender: TObject);
var
buf : string;
begin
IdTCPClient1.Connect;
SetLength(buf, 10);
IdTCPClient1.ReadBuffer(buf[1], 10);
ShowMessage(buf);
end;


запускаю, нажимаю на кнопку - висит конкретно. понятное дело - я http запрос не отправил.

кладу антифриз, запускаю, нажимаю на кнопку - не висит.

кладу вторую кнопку

procedure TForm1.Button4Click(Sender: TObject);
begin
IdTCPClient1.Write("GET / HTTP 1.0"#13#10#13#10);
end;


запускаю, нажимаю на кнопку1, кнопку2 - получаю ответ.

но в любом случае с потоком лучше, я думаю.


 
$hade   (2002-01-24 15:30) [17]

нее... AntiFreeze работает...
буду пробовать с потоками...
тут вот еще вопросы появились по ходу дела...))
1. OnWork,OnWorkBegin,OnWorkEnd - что ет за события и с чем их едят? :)
2. SendCmd, CheckForCmd... - что за команда (то есть как с етим работать...)

а в принципе хотелось бы найти доки и/или примерчики по использыванию Indy...


 
nikkie   (2002-01-24 16:47) [18]

сайт инди http://www.nevrona.com/indy
там есть хелп, демо, статьи.
и хелп и демо, правда, обычно несколько отстают от актуальной версии.
с дельфи 6 идет версия 8.


 
$hade   (2002-01-24 17:03) [19]

ага...я как раз забыл сказать что кроме Nevrona...я там ужо бывал...ничего нового почти не узнал..((



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

Форум: "Сети";
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.006 c
3-22579
polarbear
2002-03-17 20:46
2002.04.08
Как остановить сервер FireBird из командной строки под Win9x?


1-22641
DimaIv
2002-03-27 06:48
2002.04.08
Работа с масивом


1-22651
Chris
2002-03-27 11:33
2002.04.08
Панель, выступающая за форму


1-22707
PEC
2002-03-26 12:24
2002.04.08
Привет народ


1-22757
sammy
2002-03-27 09:00
2002.04.08
Keyboard Layout





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский