2012-04-24 2 views
5

Мне нужно подключиться к тысячам клиентов через TCP на проприетарном протоколе, чтобы циклически получать данные. Мне нужно написать приложение .NET на C#.Опрос в тысячах TCP-сокетов

Первой попыткой было создать для каждого сокета tcp собственный поток, который работает, но требует много использования процессора.

Я выяснил, что было бы лучше использовать .NET threadpool. Насколько я понимаю (http://msdn.microsoft.com/en-us/library/ms973903.aspx), я мог бы использовать таймеры, чтобы каждый сокет получал данные циклически за данный период (например, 1 сек). Это не работает для меня, потому что сокеты отключены после того, как соединение было открыто, потому что есть много дополнительных сокетов, которые нужно открыть, прежде чем снова откроются открытые сокеты.

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

+2

Слова «тысячи» и «нитки» не идут рука об руку. Попытайтесь выяснить, можете ли вы использовать ключевое слово 'await' для продолжений, это позволит вам писать код против блокировки портов, не очень часто блокируя код. Это своего рода принцип, стоящий за Erlang и Stackless Python - два языка, построенные специально для параллельного взаимодействия. –

+1

Зачем вам проходить через клиентов для получения данных? было бы проще (хотя это относительный) просто сохранить асинхронное чтение, размещенное на каждом сокете и обработать данные по мере их поступления. Если вам действительно нужны циклические чтения, вы можете отложить повторный просмотр асинхронного чтения до тех пор, пока не будут обслуживаться все остальные сокеты. –

+1

просто не опросить. –

ответ

6

Попробуйте использовать Socket's high performance API, который позволяет одновременно получать данные на очень большом количестве сокетов без использования одного потока на разъем. В нижней части статьи есть ссылка на полный образец. В статье MSDN также есть образец для SocketAsyncEventArgs class.

+0

Высокопроизводительный API Socket, похоже, способен обрабатывать множество входящих соединений. Мне нужно открыть эти соединения. Можно ли использовать также высокопроизводительный API Socket для этой цели? – sqeez3r

+1

Да, создайте и откройте один сокет на каждого клиента, затем используйте ['Socket.ReceiveAsync()'] (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receiveasync.aspx). –

+1

Я реализовал его таким образом, и он отлично работает. Благодаря! – sqeez3r

0

Почему бы не заполнить очередь с адресами, которые необходимо опросить, и попросить пул потоков взять элементы из очереди для обработки?

Как только вы закончите с элементом, нажмите его в обратную сторону очереди.

+3

С одной стороны, если у вас много неактивных подключений, вы будете тратить много времени на их проверку без причины. –

+0

Я думаю, что это займет слишком много времени для тысяч подключений. Мне нужны обновления со всех сокетов каждую секунду, если это возможно. – sqeez3r