Ограничение Windows на количество одновременно открытых сокетов / соединений на машину - PullRequest
4 голосов
/ 28 февраля 2012

Допустим, у меня есть Windows 7 с одним реальным сетевым интерфейсом и несколькими интерфейсами обратной связи.У меня есть сервер с поддержкой IOCP, который принимает подключения от клиентов.Я пытаюсь смоделировать как можно больше реальных клиентских подключений к серверу.

Мой клиентский код просто устанавливает X количество соединений сокетов (обратите внимание, что клиент привязывается к данному интерфейсу):

        const Int32 remotePort = 12345;
        const Int32 MaxSockets = 60000;

        Socket[] s = new Socket[MaxSockets];
        IPEndPoint bindEndpoint = new IPEndPoint(IPAddress.Parse(args[0]), 0);
        for (Int32 i = 0; i < MaxSockets; i++)
        {
            s[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s[i].SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            s[i].Bind(bindEndpoint);
            s[i].Connect(args[1], remotePort);

            IPEndPoint socketInfo = (IPEndPoint)s[i].LocalEndPoint;
            Console.WriteLine(String.Format("Connected socket {0} {1} : {2}", i, socketInfo.Address, socketInfo.Port));
        }

В петлевом интерфейсе у меня есть несколько IP-адресов, которые я использую для привязки.Кроме того, я также использую настоящий интерфейс для привязки.Я столкнулся с проблемой, когда количество открытых сокетов составляет около 64 КБ на машину:

Необработанное исключение: System.Net.Sockets.SocketException: Операция над сокетом не может быть выполнена, поскольку в системе недостаточнобуферного пространства или из-за переполнения очереди

Я пробовал несколько беспомощных вещей, таких как: - установка MaxUserPort на максимальное значение и некоторые другие рекомендуемые параметры TCPIP в реестре.- пытаться запустить два сервера на разных интерфейсах (реальные интерфейсы и шлейф) и использовать несколько клиентов.

Это известное ограничение в Windows или его можно как-то преодолеть?

Спасибо запомощь!

Ответы [ 3 ]

3 голосов
/ 29 февраля 2012

Я нашел на какой-то странице Microsoft, что:

... HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort Подраздел реестра определяется как максимальный порт, до которого могут быть выделены порты для подстановочных знаков. Значение записи реестра MaxUserPort определяет динамический диапазон портов ...

Итак, если я заставлю конечную точку использовать определенный порт, например,

IPEndPoint bindEndpoint = new IPEndPoint(IPAddress.Parse(args[0]), 54321);

Тогда я могу открыть более 64K одновременных сокетов в системе.

1 голос
/ 29 февраля 2012

В вашем примере кода вы звоните Bind(bindEndpoint), но не показываете, как определяется bindEndpoint. Проверьте, что:

  • Ваша система фактически имеет несколько IP-адресов (обратная связь не учитывается)
  • Вы фактически устанавливаете IP-адрес конечной точки на IP-адрес (не петлевой)
  • Связки распределяются по нескольким IP-адресам

Адрес обратной связи не считается, потому что многие системы обращаются с ним специально для маршрутизации и привязки. Таким образом, привязка к портам в кольцевом шлейфе может поглощать порты по всем адресам так же, как если бы вы привязывались к INADDR_ANY (0.0.0.0).

0 голосов
/ 28 июня 2016

Как TCP, так и UDP используют 16-разрядное целое число без знака для обозначения номера порта. Я не думаю, что какая-либо реализация в какой-либо операционной системе сможет открыть в лучшем случае более 65535 сокетов на связанный адрес. Кроме того, я не удивлюсь, если Windows не реализует полностью изолированные таблицы состояний для каждого адаптера или каждого связанного адреса, а использует глобальную таблицу состояний. В таком случае это будет ограничение сетевой архитектуры Windows вместо мягкого настраиваемого ограничения.

...