Форум: "Сети";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
ВнизПосоветуйте с выбором компонента для работы с TCP Найти похожие ветки
← →
Piter © (2004-08-12 00:59) [0]Пробовал и не надо предлагать TTcpClient.
Также не предлагайте пока самому работать с WinApi напрямую.
Сейчас перешел на TIdTCPClient - вроде ничего, но есть маленькая проблема... Вообще, хотелось бы спросить - у компонентов, которые работают в блокирующем режиме логика должна быть такова - подсоединяешься, вызываешь Recv (ReceiveBuf или как там этот метод у комонента называется), если он вернул ноль байт - это означает, что соединение разорвано, верно?
Если верно, то проблема в том, что бывает Recv долго не отдает управление, причем все данные уже переданы. В конце концов, после 30 секунд ожидания управление возвращается и оказывается, что получено ноль байт.
То ли это особенность TIdTCPClient, то ли это глюк сервера (после передачи всех данных он не рвет соединение) - никак не пойму. Стоит сказать, что работаю я с протоколом HTTP и тот же запрос IE почему-то отрабатывает быстро без всякого ожидания. То ли... я вот сейчас подумал, может TIdTCPClient вовсе и не в блокирующем режиме работает? По всем признакам похоже на блокирующий режим, но может я чего не знаю...
Вот я так сумбурно все описываю, но это потому что я вижу следствие, а причин не знаю.
Вот можно сформулировать несколько подвопросов, которые и составляют мой больщой вопрос:
1) TIdTCPClient работает в блокирующем режиме?
2) Если компонент в блокирующем режиме при вызове Recv возвращает ноль - это означает, что соединение разорвано?
3) кто при HTTP соединении должен разорвать соединение, сервер? И есть ли какие-то признаки для клиента, что соединение можно разорвать
Ну и последнее - посоветуйте компонент, который корректно работает в блокирующем режиме. Только не приводите все компоненты, которые знаете. Хочется спросить людей, которые хотя бы год работают с компонентом и не выявили в нем никаких изъянов. Компонент должен уметь работать в блокирующем режиме, то есть на каждое соединение программа создает новый поток, в новом потоке создается экземпляр данного компонента и идет работа.
← →
nikkie © (2004-08-12 01:53) [1]все упорствуешь, не хочешь готовой компонентой воспользоваться...
IdHTTP.Get и все проблемы решены. ну или почти все...
ЗЫ инди только в блокирующем режиме и работает. иначе не умеет.
← →
nikkie © (2004-08-12 02:05) [2]а если хочется сам http реализовывать, то удобно пользоваться методом Readln, а не Recv.
← →
alienserg (2004-08-12 04:01) [3]Piter © (12.08.04 00:59)
Компонент должен уметь работать в блокирующем режиме, то есть на каждое соединение программа создает новый поток, в новом потоке создается экземпляр данного компонента и идет работа.
Разве блокирующий режим каким либо образом обязывает программу создавать экземпляр компонента динамически и запускать его в отдельном потоке?
Если ты имеешь ввиду заморозку формы при выполнении операции в сокете в блокирующем режиме, то Indy предлагает другое решение этой проблемы. Надо сбросить _один_на_все_приложение_ компонент TIdAntiFreeze. И все. Формы замораживаться не будут во время работы TIdTcpClient.
С другой стороны никто не мешает создать экземпляр ручками и запустить его в отдельном потоке. Я так и делаю в некоторых случаях.
По поводу разрыва коннекта сразу после считывания... Разве это кто-то регламентирует для TCP? TIdTcpClient не обрывает в автомате коннект после считывания.
В демках Indy есть пример TCP Chat.
Там считывание организовано через readln по таймеру.
если считаное - пусто, то ждем следующей строки.
Если пришла строка, то анализируем ее.
Если понял, что пришло уже все, что надо, то тогда делай Disconnect.
Тут ранее критиковалось использование таймера для этого дела, но я минусов не вижу. Когда я получаю ответ, требующий длительной обработки, то отключаю на это время таймер.
С Indy работаю как раз около года и впечатления только положительные.
Просто с самого начала надо учесть несколько нюансов.
Из тредов рисовать на форме только через Synchronize/TIdSync/PostMessage
и не забывать про TIdAntiFreeze.
Если перед тобой стоит задача коннект - посылка команды - прием ответа - дисконнект, то может действительно стоит прислушаться к nikkie © (12.08.04 01:53) [1] а не мучаться на низовом уровне с TCP...
← →
Piter © (2004-08-13 01:42) [4]alienserg (12.08.04 4:01) [3]
Там считывание организовано через readln по таймеру.
если считаное - пусто, то ждем следующей строки
а разве не верно, что если ничего не пришло - значит коннект разорван? Иначе как определить разрыв соединения?
Все таки жду советов по выбору TCP компонента. Это и не только для клиентов, а вообще для всех моих сетевых приложений
← →
Piter © (2004-08-13 13:28) [5]nikkie © (12.08.04 2:05) [2]
а если хочется сам http реализовывать, то удобно пользоваться методом Readln, а не Recv
а где у TidTCPClient есть метод ReadLn?!
← →
Digitman © (2004-08-13 14:11) [6]
> жду советов по выбору TCP компонента
если планируется мультиплатформенность приложения, то Инди подойдет
если планируется работа только под Win, то Инди далеко не панацея ... по тому же TCP работает и старая борландовская "связка" - TServer/ClientSocket, которая "заточена" именно под Win и потому дает ощутимую эффективность и гибкость в использовании - никаких излишеств, чистой воды транспорт, безо всяхих бестолковых "наворотов" поверх него, на выбор два режима - блокирующий синхронный и неблокирующий асинхронный с использованием механизма оконных нотификаций
← →
nikkie © (2004-08-13 17:08) [7]>а где у TidTCPClient есть метод ReadLn?!
унаследован от TIdTCPConnection.
← →
alienserg (2004-08-13 22:31) [8]Piter © (13.08.04 01:42) [4]
а разве не верно, что если ничего не пришло - значит коннект разорван? Иначе как определить разрыв соединения?
Не-а, неверно. Надо специально делать Disconnect или на сервере или на клиенте, чтобы разорвать соединение.
Для того, чтобы определить непредвиденный разрыв соединения, надо регулярно слать на сервер короткие keep-alive сообщения. Если операция записи в сокет выдала ошибку, то значит коннект разорвался. А на сервере регулярно проверяй, когда в последний раз юзер проявлял признаки жизни. Если молчание затянулось, то это значит, что коннект непредвиденно разорвался.
Все таки жду советов по выбору TCP компонента.
Вот я тебе и советую использовать Indy :) Один из самых сильных доводов в пользу Indy это очень качественная поддержка в ньюсгруппах. Советую полазить по ним.
Digitman © (13.08.04 14:11) [6]
если планируется работа только под Win, то Инди далеко не панацея...
А какие явные изъяны Indy под Win ты видишь? Отсутствие асинхронного режима?
← →
Piter © (2004-08-13 22:57) [9]Digitman © (13.08.04 14:11) [6]
по тому же TCP работает и старая борландовская "связка" - TServer/ClientSocket, которая "заточена" именно под Win и потому дает ощутимую эффективность и гибкость в использовании
а в чем выражается гибкость и эффективность? В чем недостаток Indy в этом аспекте?
Кросс-платорменность вовсе не нужны. И хочется задать вопрос - чем Indy уступает? Скорость, размер кода, требования к ресурсам?
nikkie © (13.08.04 17:08) [7]
унаследован от TIdTCPConnection.
сории, это меня уже колбасит
← →
Digitman © (2004-08-16 16:46) [10]
> Piter © (13.08.04 22:57) [9]
> в чем выражается гибкость и эффективность?
потому что это чистой воды транспорт.
практически безо всяких прикладных "нахлобучек" поверх негохош синхронный, а хош асинхронный - выбирай на вкус
> чем Indy уступает?
как правило масса лишнего-ненужного
и выбора нет - транспорт только синхронный
← →
alienserg (2004-08-16 18:06) [11]Digitman © (16.08.04 16:46) [10]
как правило масса лишнего-ненужного
Очень спорное утверждение :)
Если много всего, то это еще не значит, что оно "лишнее-ненужное". Народ пользуется и нахваливает. По количеству серьезных приложений Indy вряд ли уступет родным борландовским TServer/ClientSocket. Во всяком случае активность ньюсгрупп по Indy на порядок больше, чем в ньюсах, посвященных TServer/ClientSocket.
Производительность и нагрузочная способность Indy выше всяких похвал. Indy10 использует даже NT Fibers. Народ тестил и получается, что такой подход снижает загрузку процессора раза в 3-4 по сравнению с использованием тредов в Indy9. В качестве теста брался видеосервер, отдающий в среднем около 10Gbit/sec суммарных видеопотоков около 100 юзерам. Это при том, что и к Indy9 не было никаких нареканий по производительности.
← →
Fay © (2004-08-16 21:08) [12]2 alienserg (16.08.04 18:06) [11]
>> В качестве теста брался видеосервер
Сколько процессоров?
← →
alienserg (2004-08-16 23:57) [13]Fay © (16.08.04 21:08) [12]
Сколько процессоров?
Не могу сейчас припомнить. В ньюс-группе один из девелоперов обменивался с разработчиками мнением об Indy10 и приводил эти цифры, глядя на свой сервер. Или двухпроцессорная машина была или обычная. По идее кол-во процессоров не должно сильно влиять на картину, поскольку основной выигрыш при переходе от тредов к нитям именно в легкости переключения между нитями. Переключение между тредами более тяжелая операция для операционной системы.
Жаль что Indy10 несовместима с Indy9 и пока только Beta...
← →
alienserg (2004-08-22 01:35) [14]alienserg (16.08.04 18:06) [11]
в среднем около 10Gbit/sec суммарных видеопотоков около 100 юзерам.
Прошу извинить, здесь ошибка конечно. Надо читать 10Mbit/sec...
← →
Terminus (2004-09-30 00:23) [15]Господа, я смотрю, тут есть довольные пользователи Indy :)
Рискну задать пару вопросов :)
1. Если и TCP клиент и сервер запущены на ОДНОЙ машине, иногда во время работы происходит, так сказать, саморассоединение клиент и сервера. :) Такого не наблюдается, кажется, если сервер и клиент разнести на разные машины... Может знаете, в чем тут может быть дело?
2. Опять же сервер и клиент. Нужно передавать данные по несколько сотен KB. Но сервер же не знает, висит клиент на мопеде или на выделенке. Соответственно, не известно, какую скорость передачи должен обеспечивать сервер (уже на уровне приложения), чтобы не завалить лагучего клиента. :) Получается, единственный выход, это предлагать клиенту самому выбирать свой тип соединения, передавать его на сервер, и чтобы сервер (тут я уже имею в виду серверное приложение) уже исходя из этого устанавливал скорост передачи?
← →
Terminus (2004-09-30 00:33) [16]И еще. Стоит ли, на Ваш взгляд, качать Indy10? Есть там что-то принципиально новое?
← →
Terminus (2004-09-30 02:37) [17]Эх... Поставил Indy 10. Раньше все просто было. "AThread.Connection.ReadBuffer" и пихаю данные куда хочу. А теперь непонятно как вообще даные читать и куда пропал TIfPeerThread. То ли TIdContext вместо него, то ли еще что-то... :(
← →
Digitman © (2004-09-30 08:28) [18]
> Может знаете, в чем тут может быть дело?
знаем.
ошибка в 17-й строке.
← →
Terminus (2004-09-30 19:56) [19]Черный юмор. Типа умничаем. :) Ошибками кода проги это вызвано быть не может. Исключено. Ошибка может проявится (а может и нет), даже тогда, когда обмена макетами вообще не происходит. И я не зря упомянул, что такое проявляется только на одной машине. Т.е. это либо особенность поведения сокетов, либо особенность Indy. Вот об этом я и спрашивал....
← →
Palladin © (2004-09-30 20:25) [20]Черный юмор? Он появляится лишь потому что у всех работает, а у отдельных личностей почемуто нет... тут просто напрашивается, а что это с отдельными личностями такое происходит...
← →
Terminus (2004-09-30 20:30) [21]Т.е., надо понимать, у всех остальных особо "продвинутых" личностей коннект TCP клиента и сервера на _одной_ машине стабильно держится по нескольку десятков минут, и ни разу не разрывается с неплохим, в общем то, сообщением "Connection Closed Gracefully"? :) При том что в проге нет ни одного вызова закрытия соединения. Только если клиентская прога закрывается. Сообщение то характерно именно для правильного дисконнекта, чего тут нет.
← →
Terminus (2004-09-30 20:38) [22]Забыл дописать. Речь идет об WinXP.
И еще. Есть такая вещь как "TCP/IP мост для сервера ФБП". Что это такое, мне не интересно, но автор в старых новостях сообщает следующее:
"Устранена трудно отлавливаемая ошибка, выражавшаяся в том, что Клиент-FC неожиданно сообщал «Connection Closed Gracefully». А дело было вот в чем. Мост, ожидая ответа сервера, сканирует каталог обмена на предмет обнаружения файла *.OUT. Как только такой файл появлялся, производилась попытка его открыть. Но если, к моменту открытия Мостом, сервер еще не успевал его закрыть, то возникало исключение (exception), который не правильно обрабатывался - приводил к сбросу соединения и, соответственно, к недоумению Клиента-FC. Любопытно, что на Windows98 эта ошибка никогда себя не проявляла, а выплыла при тестировании под NT и XP"
Т.е. та же ситуация. Если не работа на одной машине, то, во всяком случае, использование общих ресурсов и, как следствие, конфликт...
Есть что-нибудь сказать более интеллектуально насыщщеное, чем размышления об "отдельных личностях"?
← →
Terminus (2004-09-30 20:41) [23]Жаль, сообщения править нельзя, приходится флудить...
Конфликта ресурсов на винте между клиентом и сервером на уровне приложения нет. Нечему конфликтовать. Если только Indy... Хотелось бы докопаться до истины :)
← →
Rouse_ © (2004-09-30 20:49) [24]> Если и TCP клиент и сервер запущены на ОДНОЙ машине, иногда
> во время работы происходит, так сказать, саморассоединение
> клиент и сервера. :) Такого не наблюдается, кажется, если
> сервер и клиент разнести на разные машины... Может знаете,
> в чем тут может быть дело?
в IdTCPClient1.Disconnect
> Соответственно, не известно, какую скорость передачи должен
> обеспечивать сервер ...
Получается, единственный выход, это предлагать клиенту самому выбирать свой тип соединения
А сервер или клиент ничего выбирать не должен в плане скорости, не его это проблемы и уровень...
← →
Terminus (2004-09-30 21:19) [25]> IdTCPClient1.Disconnect
Ну наверное я убедился перед тем, как сюда писать, что вызова Disconnect у меня в проге не происходит. :)
Жаль, ничего дельного пока не услышал... Уверен, у Palladina и Digitmana есть решения, просто они стесняются ;)
> А сервер или клиент ничего выбирать не должен в плане скорости, не его это проблемы и уровень...
Этот вопрос благополучно разрешился...
← →
Terminus (2004-09-30 21:21) [26]И контрольный вопрос. Кто-нибудь держал на _одной_ машине Indy TCP клиент и сервер в течении хотя бы 10 минут, и при этом без вышеозначеной ошибки?
← →
Digitman © (2004-10-01 08:49) [27]
> Terminus
чем "умничать" про какие-то там "серверы ФБП" и пр., ты бы лучше код своего сервера показал, если не весь, то хотя бы ключевые моменты алгоритмов ... за одно и посмотрим, умеешь ли ты отделять "зерна от плевел"
← →
Terminus (2004-10-01 19:58) [28]> чем "умничать" про какие-то там "серверы ФБП" и пр., ты бы лучше код своего сервера показал, если не весь, то хотя бы ключевые моменты алгоритмов ... за одно и посмотрим, умеешь ли ты отделять "зерна от плевел"
Чудно. Какие из 25 тыс.строк считать ключевыми? :)
Про ФБП я цитировал человека, предположив, что проблема может быть в самом Indy. Ошибки в своем собственном коде я бы найти смог :)
← →
Verg © (2004-10-01 21:27) [29]
> Terminus
Ой, ну слушай, на самом деле, если ты считаешь, что "вся рота не в ногу", то и привел бы тот код, который бы не смог:
> Кто-нибудь держал на _одной_ машине Indy TCP клиент и сервер
> в течении хотя бы 10 минут, и при этом без вышеозначеной
> ошибки
Эталонный, воспроизводящий, как тебе кажется, этот дефект в чистом виде, в наикратчайшем исполнении, в очевидности своей форме, чтобы каждый мог убедиться, что ты прав, а не просто "сотрясаяешь воздух громкими звуками", убеждая всех в абсолютной безгрешности своего кода.
Обычно глобоко зарытые ошибки, которые на ранней стадии не выявлены, вживаются в сознание как "неоспормые" истниы (псевдо-аксиомы), и только лишь потому, что влияние их по (не)счастливой случайности не было обнаружено на тех самых ранних стадиях разработки.
А вот это -
> Ошибками кода проги это вызвано быть не может. Исключено.
>
-- наизлейшее, наивреднейшее заблуждение... при том настолько же примитивное, как и известная пословица про "вся рота не в ногу".
Тебе тысячи програмеров, если бы не поленились, плюнули бы в нос совершенно обратным утверждением и тебе бы все равно пришлось бы либо предъявить аргументы, либо задуматься над тем как тебе доказать то, что трясет тебя не потому, что у тебя колеса кривые, а потому что, он (автобан) неровный. То есть на собой....
← →
Terminus (2004-10-02 18:59) [30][b]Verg[/b]
Вроде много сказано, и вроде не сказано ничего :)
В общем так... Правильный дисконнект инициируется клиентом только в двух случаях:
1. Клиент жмет кнопку Выход. При этом вызывается idTCPClient.Disconnect или что-то в этом роде.
2. Клиент выходит из программы.
Нигде больше вызова дисконнекта не происходит в принципе, уж поверьте :)
Дисконнект со стороны сервера вообще никогда не инициируется, т.е. выход всегда происходит как бы по инициативе клиента.
Сама модель клиента/сервера ничем не отличается от стандартного примера из Indy 9 :)
А на самом деле получается, что у клиента вылетает ошибка "Connection Closed Gracefully", при этом клиент и сервер продолжають работать.
1. Ошибка может не вылететь никогда (хоть бегай, хоть бей, хоть что делай)
2. Может вылететь сразу при коннекте к серверу еще до того, как клиент даже выскажет пожелание появится на карте. Т.е. тогда, когда с ним вообще никакой работы казалось бы, и происходит только обмен пинговыми пакетами по одной и той же схеме.
Вот такие пироги...
При этом, хочу подчеркнуть в сотый раз, ошибка возникает ТОЛЬКО у того клиента, который запущен на одной машине с сервером.
Возможно, что Delphi, например, что-то неверно обрабатывает (Delphi v5.1). Не раз я уже слышал слухи о глюках с ним, но за последние 4 года ни с чем подобным не сталкивался...
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.04 c