При выполнении метода Connect, если порт открыт все как-бы хорошо и быстро, но в противном случае - очень большая задержка.....особенно если комп вообще выключен или не существует.
Как бы побыстрее узнать.... какой-нить тайм аут уменьшить.... или как вообще определить до открытия порта о том, что по данному IP включен компьютер. Может кто скажет как это реализовывается в C++...
[C#] или [C++] Присоединиться к порту29.11.02 19:19 Автор: Killer{R} <Dmitry> Статус: Elderman
Вариант 1)Юзать асинхронные сокеты.
Вариант 2)Делать второй поток для коннекта.
В обоих случая обязательно сделать следующее:
int sc=socket(AF_INET,SOCK_STREAM,0);
linger lng;lng.l_onoff=1;lng.l_linger=0;
setsockopt(sc,SOL_SOCKET,SO_LINGER,(char *)&lng,sizeof(lng));
если такого не сделать то при закрытии сокета в процессе установления соединения в NT/2000 происходит memory leak в nonpageable pool(~40000 операций прерванного коннекта и систему придется ребутить)
Минус данной реализации.
Неблокирующий сокет нельзя сделать блокирующим после connectа. Это не очень приятно.
Плюс. Не надо создавать отдельных потоков и потом их убивать. К тому же в результате вызова connet сокет остается привязанным к заданному адресу, поэтому если надо повторить connect то возможно прийдется немного подождать, закрыть сокет и опять открыть.
Есть как минимум два пути решения проблеммы:29.11.02 15:24 Автор: PS <PS> Статус: Elderman
1. Правильный - я его не знаю ;)
2. Делать connect() в отдельном потоке. А, допустим, основной поток заснет на секунду-другую... Если за это время отдельный поток не выставит ни какого флага, типа все ок, то прибиваешь его и считаешь что коннект не возможен.
На всякий случай, close такому сокету все же сделай (что б не получилась ситуация, что сокет приконектился, а поток флаг поставить не успел, а его тут взяли и прибили).
Всем огромное спасибо29.11.02 21:57 Автор: Step <Step Alex> Статус: Member Отредактировано 29.11.02 21:59 Количество правок: 1
Сделал все таки на ICMP....там выставил тайм ауты... в общем работает быстро.
Хотелось бы, что бы кто то, типа, посмотрел и от..... ну в общем покритиковал, но стремно такую хр..нь показывать. Если у кого есть желание - хотелось бы узнать мнение.
По голове тока не бить :-). Я в бывалые годы не плохо программил( и на машинных кодах тоже). Была у меня к стати самая короткая программа, то ли 3, то ли 2 бита - комп перезагружала, но потом ушел в сторону, всякое администрирование маздая, а вот сейчас снова захотелось, ну чисто для себя.
Странно, мне это оже пришло в голову, но я сомневался29.11.02 16:11 Автор: Step <Step Alex> Статус: Member Отредактировано 29.11.02 16:15 Количество правок: 1
И всетаки попробую...
Хотя на "прибивание" потока тоже уйдет время и я думаю сравнимое с ожиданием соединения....
Не сравнимое ! 20 секунд - это слишком круто для прибивание потока ;) И именно столько у меня висит connect ожидая ответа из "космоса"29.11.02 16:18 Автор: PS <PS> Статус: Elderman
Создать сразу множество потоков.... т.е. для каждого коннекта создается свой поток и таки образом, скажем 150 компьютеров проверяются одновременно..... не заглушит ли это систему? И вообще есть какие либо граничения на колличество запущенных потоков?
Не советую ;)29.11.02 16:54 Автор: PS <PS> Статус: Elderman
> Создать сразу множество потоков.... т.е. для каждого > коннекта создается свой поток и таки образом, скажем 150 > компьютеров проверяются одновременно..... не заглушит ли > это систему? И вообще есть какие либо граничения на > колличество запущенных потоков?
Ограничение есть, но сколько - не знаю. Дальше можно только абстрактно рассуждать о планировщике, об очереди задач и пр.
Но в любом случае открывать 150 потоков что бы узнать кто жив в сети, а кто нет - не разумно.
Гораздо эффективней сделать два RAW сокета и через первый послать 150ти машинам тобой сформированый пакет на соединение, а на втором смотреть траффик. Те машины с которых пришел ответ - живы, с которых не пришел - увы.
Реализовать это немного сложней чем открывать потоки с connect, то зато более эффективно.
10 секунд у меня29.11.02 16:30 Автор: Step <Step Alex> Статус: Member
> Но я так понимаю, что покуда поток не закончит хотя-бы один > уже исполняющийся опрератор, он прерван > не будет...а это как раз connect...
1. Ты можешь бросить такой поток на произвол судьбы. Через N секунд он выйдет из connect, если к этому времени ты решишь, что с сокетом больше не работаешь и выставишь флаг, то поток, после успешного connect сам закроет сокет, при неудачном - просто завершится.
Таким образом ты остановишь выполнение программы только на тот timeout который определишь сам (тот самый Sleep в основном потоке). То что у тебя будет происходить параллельно - тебе будет параллельно ;)
2. На крайняк можешь использовать TerminateThread(). Страшно ? Да. Но прибьет сто процентно. Не зависимо от того, что у тебя там выполняется.
Попоробую...сразу представил себя "Терминаторм" :-)29.11.02 16:49 Автор: Step <Step Alex> Статус: Member
А может пинговать другой хост по ICMP? Так тебе не надо самому отслеживать таймауты, если заюзаешь icmp.dll (это под виндой)29.11.02 17:16 Автор: HandleX <Александр М.> Статус: The Elderman
А может пинговать другой хост по ICMP? Так тебе не надо самому отслеживать таймауты, если заюзаешь icmp.dll (это под виндой)29.11.02 19:42 Автор: Step <Step Alex> Статус: Member
Может и можно , но есть два НО
1. Мне все таки надо знать -открыт порт или нет, хотя пингование могло бы снять вопрос о доступности хоста, и не тратить время на открытие порта если нет ткого компа.
2. Как не пытался прикрутить ICMP - так и не понял, как его поюзать...