Сетевые FTP сервера
Релиб
Форумы       Участники    Календарь    Кто он-лайн?
Добро пожаловать, гость ( Вход | Регистрация )
        



Сетевые FTP сервера Expand / Collapse
Автор
Сообщение
15.11.2006 16:27
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 14.03.2007 1:06
Сообщ.: 8, Visits: 46
Доброго времени суток!

Существует задача
Получить список всех локальных FTP-серверов, находящихся в онлайне. Это значит, что есть диапазон IP-адресов 192.168.*.*, каждый из которых необходимо проверить на наличие на нём ftp-сервера (TCP, 21 порт).

Как я решал эту проблему

1. Пробую "влоб" пытаться подключиться к серверам через System.Net.Sockets.TcpClient. Данный вариант не устраивает по двум причинам: необходимо сильно уменьшить время ожидания подключения, т.к. стандартное значение таймаута слишком велико для столь немаленького диапазона хостов. Как менять таймаут подключения (это ни SendTimeout, ни ReceiveTimeout) я не нашёл. Ситуация ещё ухудшается тем, что в случае невозможности подключения вылетает исключение, а его отлов это снова большие потери во времени и уже поэтому не лучший вариант.

2. Да, можно использовать асинхронную операцию BeginConnect, но она не устроивает по тем причинам, что один сокет нельзя одновременно использовать для нескольких подключений (кто бы сомневался), а создание большого числа сокетов тоже нежелательно, в итоге это может кончиться сотнями открытых портов, всяческими переполнениями, т.к. насколько я знаю, на их количество в системе тоже есть ограничение.

3. Хорошо, таймаут можно настроить у фунции System.Net.NetworkInformation.Ping.Send, а потом в случае положительного результата можно уже пробовать подключаться по 21 порту. Но: на компьютере с доступным FTP сервером никто не запрещает заблокировать приём или ответ на ICMP echo message - т.е. часть адресов мы потеряем.

Вопрос остаётся - как с минимальными потерями во времени получить полный список активных FTP в локальной сети?
Сообщ. #907559
15.11.2006 17:01
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
Я бы пробовал комбинировать п.1 и 2. В любом случае придется перебирать все адреса, по другому никак.
Сообщ. #907566
15.11.2006 23:04
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 14.03.2007 1:06
Сообщ.: 8, Visits: 46
Ура. Ни на gotdotnet, ни на realcoding ответа так и не дождался. :)

1. Весь диапазон адресов обрабатывать придётся - это не вызывает сложностей или каких-либо проблем. Кроме одной... Если над каждым неработающим адресом мы будем работать хотя бы даже по паре секунд, то опрос всей сети займёт огромное время.

2. Описанный мной второй вариант всецело основан на первом (всё та же попытка подключиться через сокет), только с асинхронной структурой. Как уже написал, и у него есть куча недостатков.

Поэтому по сути вопрос можно свести к задаче об изменении значения таймаута ожидания ответа на запрос подключения. Подключаться можно абсолютно любым способом.
Сообщ. #907593
16.11.2006 13:58
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
Конечно это займет много времени. Шутка ли проверить 65 тысяч машин адресов. Пара секунд на одну проверку это даже мало. Не факт что каждый сервер успеет ответить в течение такого короткого интервала.

Механизм исключений замедляет поиск, все верно, но в среде .NET нет классов не использующих исключения. Можно начать использовать функции WinAPI из Windows Sockets 2 там исключений точно нет. Как изменить таймаут соединения в .NET я не знаю.

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

Извини, что не могу дать более полный ответ подкрепленный кодом. Я не специалист в работе с сокетами.

Сообщ. #907611
16.11.2006 15:24
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 14.03.2007 1:06
Сообщ.: 8, Visits: 46
Насчёт пары секунд - врятли это мало, это очень много. В 90% случаев при нормально работающей хоть даже 10-мбитной локальной сети действительно работающий сервер сразу отвечает менее, чем за 100-200 миллисекунд, на такие ответы и надо рассчитывать в идеале.
Мне, честно говоря, не понятно, почему Ping имеет таймаут, а Connect в сокетах - нет...
Сообщ. #907615
16.11.2006 15:49
Supreme Being

Supreme Being

модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240, Visits: 65 445
Ответ в течение 100-200 миллисекунд возможен в случае незагруженной сети и низкой нагрузки на сам ftp сервер. В реальной ситуации это не обязательно будет выполняться. Я бы не стал рассчитывать на ответ в течение такого короткого интервала.
Сообщ. #907619
16.11.2006 16:02
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 14.03.2007 1:06
Сообщ.: 8, Visits: 46
Да, вполне возможно, это так. Но боюсь, что, не зная, как его значение поменять, рассуждать об этом преждевременно...
Сообщ. #907620
20.11.2006 23:43


Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 23.04.2007 23:36
Сообщ.: 1 541, Visits: 16 997
Я бы делал так:

1. Запускал бы для каждого адреса отдельный поток, который репортил бы о результате через общее для них событие. Причем обработчик события должен быть помечен как синхронизированный либо использовать локи/семафоры.

2. Таймаутом на TCP-соединениях рулить не получится даже в WinAPI. Ну, не поддерживают блокирующие сокеты таймаута... Поэтому нужно юзать неблокирующий сокет (SetSocketOption()). И самостоятельно ждать нужный таймаут.


Сообщ. #907737
22.11.2006 0:59
новичок

новичокновичокновичокновичокновичокновичокновичокновичок

участник
Last Login: 14.03.2007 1:06
Сообщ.: 8, Visits: 46
Спасиба, попробую так и делать.
Сообщ. #907820