Обработка нескольких соединений TcpClient без использования потоков - PullRequest
2 голосов
/ 04 апреля 2011

У меня есть программа на C # с множеством (скажем, около тысячи) открытых объектов TcpClient.Я хочу войти в состояние, которое будет ожидать, что что-то произойдет для любого из этих соединений.

Я бы не хотел запускать поток для каждого соединения.

Что-то вроде ...

while (keepRunning)
{
     // Wait for any one connection to receive something.
     TcpClient active = WaitAnyTcpClient(collectionOfOpenTcpClients);

     // One selected connection has incomming traffic. Deal with it.
     // (If other connections have traffic during this function, the OS
     // will have to buffer the data until the loop goes round again.)
     DealWithConnection(active);
}

Дополнительная информация:
Объекты TcpClient поступают из TcpListener.
Целевой средой будет MS .NET или Mono-on-Linux.
Протокол требует длительных периодов простоя, покасоединение открыто.

1 Ответ

2 голосов
/ 04 апреля 2011

То, что вы пытаетесь сделать, называется асинхронным шаблоном в терминологии Microsoft.Общая идея состоит в том, чтобы изменить все операции блокировки ввода-вывода на неблокирующие.Если это сделано, приложению обычно требуется столько системных потоков, сколько имеется ядер ЦП на компьютере.

Взгляните на библиотеку параллельных задач в .Net 4: http://msdn.microsoft.com/en-us/library/dd460717%28VS.100%29.aspx

Этодовольно зрелая оболочка поверх простой старой парадигмы Begin / Callback / Context .Net.

Обновление:

Подумайте, что вы будете делать с данными после того, как прочитаете из соединения.В реальной жизни вам, вероятно, придется ответить клиенту или сохранить данные в файл.В этом случае вам потребуется некоторая инфраструктура C # для хранения / управления вашей логикой и при этом оставаться в одном потоке.TPL предоставляет его вам бесплатно.Единственным недостатком является то, что он был введен в .Net 4, поэтому, вероятно, он еще не в Mono.

Еще одна вещь, которую следует учитывать, это время жизни соединения.Как часто ваши связи открываются / закрываются и как долго они живут?Это важно, потому что принятие и отключение TCP-соединения требует обмена пакетами с клиентом (который по своей природе является асинхронным, и более того - злонамеренный клиент может вообще не возвращать ACK (подтвержденные) пакеты).Если вы считаете, что этот аспект важен для вашего приложения, вы, возможно, захотите изучить, как правильно с этим справиться в .Net.В WinAPI соответствующими функциями являются AcceptEx и DisconnectEx.Вероятно, они заключены в .Net с методами Begin / End - в этом случае вы можете пойти.В противном случае вам, вероятно, придется создать оболочку для этих вызовов WinAPI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...