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

Вниз

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

Наверх




Память: 0.69 MB
Время: 0.087 c
2-1251219105
stas
2009-08-25 20:51
2009.10.25
Установлен ли сервис


11-1207080572
Lotos
2008-04-02 00:09
2009.10.25
Заполнение данных в mdvXLGrid


2-1251902073
Merlin_88
2009-09-02 18:34
2009.10.25
Помогите с Классами


1-1222031699
Д С
2008-09-22 01:14
2009.10.25
Событие показа формы.


1-1221645579
Int23
2008-09-17 13:59
2009.10.25
Можно ли перенести компонент из Д7 в Д2006





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