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

Вниз

TspClient и TspServever   Найти похожие ветки 

 
Сергей М. ©   (2009-08-13 08:13) [80]

В VCL-приложении - основной.
И он же, основной поток, у тебя вызывает метод ReceiveLn.
Пока метод не завершит выполнение, осн.поток не будет исполнять свои GUI-обязанности, что и создает иллюзию "подвисания".
Отсюда напрашивается решение: либо переносить работу с TTCPClient в доп.поток (он так же будет "зависать" на время вызова метода, но это не повлияет на работу осн.потока, ибо потоки исполняются "параллельно") либо переводить TTCPClient в режим bmNonBlocking, оставив работу с ним в осн.потоке.


 
kostyl_kostyl   (2009-08-13 10:18) [81]


> В VCL-приложении - основной.

Ну я так и думал в принципе. Вы хотите сказать, что в режима bmBlocking клиент будет ждать пока сервер не отправит ему данные? А как тогда он поймет, что все данные отправлены?


 
Сергей М. ©   (2009-08-13 10:31) [82]


> в режима bmBlocking клиент будет ждать пока сервер не отправит
> ему данные?


В этом режиме клиент вызвав ReceiveLn ждет до тех пор пока не получит строку целиком.
Если в ходе ожидания соединение будет разорвано (по инициативе сервера или по иной не зависящей от клиента причине), Receive-метод также завершит выполнение, но с возбуждением исключения.


> как тогда он поймет, что все данные отправлены?


Клиенту нет дела до отправки, он заинтересован в получении того что он ожидает.
Если клиент ожидал некую строку (по умолчанию концом строки клиент считает символы CRLF) и эта строка была успешно доставлена, то Receive-метод вернет управление, возвратив полученную строку.


 
kostyl_kostyl   (2009-08-13 10:50) [83]

Теперь все становится понятным. Спасибо за подробное объяснение.

> но с возбуждением исключения

А какой тип исключения не подскажите?
Постойте-ка, а как же тогда клиент может разорвать соединение если он ожидает конца строки в методе Receive?


 
Сергей М. ©   (2009-08-13 10:55) [84]


> как же тогда клиент может разорвать соединение если он ожидает
> конца строки в методе Receive?


Из другого потока закрыв хэндл сокета.
При этом блокирующее выполнение метода завершится с исключением.


 
Сергей М. ©   (2009-08-13 10:58) [85]


> какой тип исключения


Пардон, наврал я тебе.
Не исключение генерируется, а вызывается обработчик OnError, коему параметром передается конкретный код причины отказа. (см. WSAGetLastError)


 
kostyl_kostyl   (2009-08-13 11:11) [86]

Короче, как я понял самое простое решение сделать все в одном потоке в режиме клиента bmBlocking и наблюдать подвисания если сервер долго отвечает. Но как быть если сервер будет очень долго записывать данные, тоесть он не до конца заполнит строку и зависнет полностью. Тогда и приложение всё зависнет. Есть какие то таймауты или чтото такое?


 
Dennis I. Komarov ©   (2009-08-13 11:15) [87]


> Короче, как я понял самое простое решение сделать все в
> одном потоке в режиме клиента bmBlocking и наблюдать подвисания
> если сервер долго отвечает. Но как быть если сервер будет
> очень долго записывать данные, тоесть он не до конца заполнит
> строку и зависнет полностью. Тогда и приложение всё зависнет.
>  Есть какие то таймауты или чтото такое?

Вынеси в дополнительный поток...


 
kostyl_kostyl   (2009-08-13 11:21) [88]

Я наверно уже задолбал, но хочу спросит как будет вести себя клиент  в режиме bmNonBlocking ?
Заранее благодарю!


 
Сергей М. ©   (2009-08-13 11:31) [89]


> как я понял самое простое решение сделать все в одном потоке
> в режиме клиента bmBlocking и наблюдать подвисания если
> сервер долго отвечает


Неправильно ты понял.

Как ты будешь "наблюдать", если у тебя всего один поток (основной) и он занят ожиданием ?

Решением для одного потока (основного) будет переход к bmNonBlocking.


 
Сергей М. ©   (2009-08-13 11:59) [90]


> как будет вести себя клиент  в режиме bmNonBlocking ?


В этом режиме транспортные методы возвращают управление немедленно.

Пример для этого режима:
..

В обработчике OnError:

if SocketError <> WSAEWOULDBLOCK then TTCPClient(Sender).Disconnect;

...
ожидание и получение текстового сообщения от партнера-сервера, сервер в этом примере должен отправлять непустое сообщение, обязательно завершающееся CRLF:


ServerResponse := "";
while TCPClient.Connected and ServerResponse <> "" do begin
 ServerResponse := TCPClient.ReceveLn;
 Application.ProcessMessages;  // обработка потенциальных GUI-событий  
end;


 
kostyl_kostyl   (2009-08-13 12:14) [91]

Блин, все равно надо поток делать (а так не хочется еще и тут разбираться), но в bmNonBlocking можно хоть таймаут  сделать, как я понял... Какие то не удачные компоненты...


 
Сергей М. ©   (2009-08-13 12:28) [92]


> в bmNonBlocking можно хоть таймаут  сделать


Можно.
И в blocking тоже можно. Но при этом ты лишаешься преимущества использования функциональности метода ReceiveLn.


> Какие то не удачные компоненты


Нормальные компоненты.
Простые и понятные донельзя.
Может это у танцора проблемы ?)


 
kostyl_kostyl   (2009-08-13 15:35) [93]

Сделал вывод такой:
Снимаю блок чтобы никто не зависал
Стартую соединение
Посылаю данные
Запускаю отдельные поток
В цикле из 10 итераций со слипом в одну секунду пытаюсь принять данные.
Если принял отдаю их и как то убиваю соединение и поток. Если  по окончанию цикла убиваю соединение и поток и говорю что сервера нет.
Вопросы как убить поток из себя самого? Как понять что данные приняты? Не пропадут ли данные пока будет спать поток?


 
Сергей М. ©   (2009-08-13 15:43) [94]


> Запускаю отдельные поток


Нахрена он нужен, если ты "снял блок" ?)
В неблок.режтиме все этго расчудесно реализуется в одном-единственном основном потоке.


 
Dennis I. Komarov ©   (2009-08-13 15:59) [95]


> Сделал вывод такой:

А надо другой:
Сперва определиться какого рода информация должна приходить от сервера.
Дальше от этого пляшем:
Спроектировать протокол обмена
Реализовать сервер.
И только после этого уже заниматься клиентской стороной...


 
Anatoly Podgoretsky ©   (2009-08-13 16:06) [96]

> Сергей М.  (13.08.2009 15:43:34)  [94]

При том с диким количеством соединений.


 
Сергей М. ©   (2009-08-13 16:10) [97]

В обработчике OnTimer:

Timer.Enabled := False;
TimedOut := True;

В обработчике OnError:

if SocketError <> WSAEWOULDBLOCK then
 TTCPClient(Sender).Disconnect;


...
TCPClient.SendLn("Запрос к серверу");
Timer.Interval := 10000;
TimedOut := False;
Timer.Enabled := True;
ServerResponse := "";
while TCPClient.Connected and not TimedOut and (ServerResponse <> ")" do begin
ServerResponse := TCPClient.ReceveLn;
Application.ProcessMessages;  // обработка потенциальных GUI-событий  
end;
Timer.Enabled := False;
if TimedOut then
 ShowMessage("Прошло 10 минут, но ответ сервера в ожидаемом виде не получен")
else
 ShowMessage("Получен ответ сервера :"#10 + ServerResponse);



 
kostyl_kostyl   (2009-08-13 18:04) [98]

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


 
Сергей М. ©   (2009-08-13 18:40) [99]

Угу.
Даже из собственных штанов за это время успеешь выпрыгнуть)


 
kostyl_kostyl   (2009-08-13 18:59) [100]

Как вы думаете, наверно я думаю что не успеет потому что не сильно улавливаю вообще суть событийного подхода и думаю что каждая следующая строка строго идет за предыдущей и ничего в этот момент больше не может выполняться? Верно?


 
Anatoly Podgoretsky ©   (2009-08-13 20:00) [101]

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

Событийный (родной для Делфьи и Виндоус) когда управление передается соответствующему обрабчику при возникновение события. Порядок выполнения не определен, поток не блокируется, в состоянии обрабатывать до нескольких десятков тысяц соединений одновнеменно в одном потоке. Расплата более сложная нелинейная логика. Обычно требует построения машины состояний, что бы организовать последовательность выполнения, для распознования в каком состоянии находится соединение.


 
Сергей М. ©   (2009-08-13 20:07) [102]


> Anatoly Podgoretsky ©   (13.08.09 20:00) [101]
> Неверно, это тупой блокирующий режим


Вообще-то мы тут уже с [93] поста про неблок.режим долдоним


 
Сергей М. ©   (2009-08-13 20:21) [103]


> kostyl_kostyl   (13.08.09 18:59) [100]


Смотря что считать стоками.
Если строки искл-но твоего кода, то да - ты не улавливаешь.


 
kostyl_kostyl   (2009-08-13 21:06) [104]

Да, я совсем, аж стыдно стало, не понимал, да и сейчас особо не вкурю, что есть очень большая разница между последовательностью строк в коде, разделения его в отдельных модулях и действительной последовательности исполнения строк кода. Это всё PHP блин....


 
Сергей М. ©   (2009-08-13 21:11) [105]


> Это всё PHP блин
</>

Эт точно)

РНР - сплошной разврат, тотальное оболванивание и без того неокрепших умов)

Можно сказать - инструмент, позволяющий пирожнику, мало что смыслящему в сапогах, тачать эти самые сапоги не хуже сапожника)


 
kostyl_kostyl   (2009-08-13 21:28) [106]

Не хочется конечно разводить тут холивар, но PHP действительно очень опасный язык в плане тенденции "общего" заблуждения по поводу его простоты. Динамическая типизация, тесная связь с окружением и основы UNIX должны все время быть в кеше мозга, чего естественно многие новички да и старички не делают. Жаль, что я уже не застал время С/С++. Высокоуровневость упрощает жизнь, но ограничивает развитие. То же самое могу сказать и о Delphi. Репид девелопмент оболочка заставляет начинающего думать о Delphi также, как и о PHP, разве что не в такой степени. Но ведь она такая совсем не для этого. Ладно. Спасибо большое всем за подсказки.


 
Anatoly Podgoretsky ©   (2009-08-13 21:30) [107]

> Сергей М.  (13.08.2009 21:11:45)  [105]

Дельфи не хуже развращает.


 
Сергей М. ©   (2009-08-13 21:32) [108]


> kostyl_kostyl   (13.08.09 21:28) [106]


> PHP действительно очень опасный язык в плане тенденции "общего"
> заблуждения по поводу его простоты


Строго говоря, тоже самое можно сказать и о Делфи.
Но выбор так или иначе за тобой)


 
Сергей М. ©   (2009-08-13 21:38) [109]


> Anatoly Podgoretsky ©   (13.08.09 21:30) [107]


Ну тебе-то ведь хорошо известно, откуда растут ноги у дельфийского разврата)

Лозунг "Делфи раньше чем горошок" культивировался и культивируется и по сей день .. всякого рода архангельскими и иже с ними)


 
kostyl_kostyl   (2009-08-14 00:45) [110]

Да, я именно так и хотел это назвать - разврат. Всё, пошел писать статью в блоге...


 
Сергей М. ©   (2009-08-14 09:01) [111]


> пошел писать статью в блоге


Порочащую "честь и достоинство" Делфи ?)


 
kostyl_kostyl   (2009-08-14 10:19) [112]

Нет, призыв к "раскрытию глаз"


 
Сергей М. ©   (2009-08-14 11:33) [113]


> призыв к "раскрытию глаз"


Ну поделись уж, не томи, кому и на что намерен "раскрывать" ?)


 
kostyl_kostyl   (2009-08-14 11:59) [114]


> Ну поделись уж, не томи, кому и на что намерен "раскрывать"
> ?)

Я еще не написал. Только начал. Хочешь, как напишу и оформлю отпишу на мыло?
А, пока есть вопрос? Почему в режиме noBlocking клиент возвращает
connect = false?


 
Сергей М. ©   (2009-08-14 12:24) [115]


> Хочешь, как напишу и оформлю отпишу на мыло?


Не хочу)
Ты лучше сюда отпишись - не одному мне любопытно)


> Почему в режиме noBlocking клиент возвращает
> connect = false?
>


Потому что в неблок.режиме операция коннекта является асинхронной : вызов метода Connect запускает эту операцию и немедленно возвращает управление. О фактическом завершении операции (успешном или неуспешном) станет известно позже.


 
kostyl_kostyl   (2009-08-14 12:36) [116]


> станет известно позже.

Ага, я понял, например в ОтЕррор может стать известно.
> Ты лучше сюда отпишись - не одному мне любопытно

Ок, как будет готова, обязательно сюда отпишу.
ЗЫ: у меня маленькая посещаемость =)


 
Сергей М. ©   (2009-08-14 12:40) [117]


> например в ОтЕррор может стать известно


Угу.


> у меня маленькая


Не беда)
Тренируй ее, культивируй - и вырастет большая-пребольшая)


 
kostyl_kostyl   (2009-08-14 14:52) [118]

Я так понял, что мне еще надо добавить:

f (SocketError <> WSAEWOULDBLOCK) and
 (SocketError <> WSAENOTCONN)  then
TTCPClient(Sender).Disconnect;


 
kostyl_kostyl   (2009-08-14 15:05) [119]

или как сервер должен реагировать? Я посылаю запрос, на сервере генерируется акцепт и сервер зависает на РесивБуфер.


 
kostyl_kostyl   (2009-08-14 16:19) [120]

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



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

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

Наверх




Память: 0.7 MB
Время: 0.03 c
15-1250843051
@!!ex
2009-08-21 12:24
2009.10.25
Как получить историю посещения браузеров?


1-1220597243
Mephala
2008-09-05 10:47
2009.10.25
Какой выбрать разделитель при передаче параметров


15-1251444756
TarenoKostanay
2009-08-28 11:32
2009.10.25
ОС


15-1251452949
xayam
2009-08-28 13:49
2009.10.25
Подскажите есть ли для php библиотека для роботы с д-ми Word .doc


1-1220057367
Deltas
2008-08-30 04:49
2009.10.25
Как получить текст окна класса TRichView?