Ограничение Windows на количество одновременно открытых сокетов /соединений на машину
Допустим, у меня есть Windows 7 с одним реальным сетевым интерфейсом и несколькими интерфейсами обратной связи. У меня есть сервер с поддержкой IOCP, который принимает подключения от клиентов. Я пытаюсь смоделировать как можно больше реальных клиентских подключений к серверу.
Мой клиентский код просто устанавливает X количество сокетных соединений (обратите внимание, что клиент привязывается к данному интерфейсу):
В петлевом интерфейсе у меня есть несколько IP-адресов, которые я использую для привязки. Кроме того, я также использую настоящий интерфейс для привязки. Я столкнулся с проблемой, когда количество открытых сокетов составляет около 64 КБ на машину:
Необработанное исключение: System.Net.Sockets.SocketException: не удалось выполнить операцию с сокетом, так как в системе недостаточно места в буфере или очередь заполнена
Я пробовал несколько беспомощных вещей, таких как: — установка MaxUserPort на максимальное значение и некоторые другие рекомендуемые параметры TCPIP в реестре. — пытаться запустить два сервера на разных интерфейсах (реальных интерфейсах и обратной связи) и использовать несколько клиентов.
Это известное ограничение в Windows или его можно как-то преодолеть?
Спасибо за помощь!
3 ответа
На какой-то странице Microsoft я обнаружил, что:
. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort Подраздел реестра определяется как максимальный порт, до которого могут быть выделены порты для подстановочных знаков. Значение записи реестра MaxUserPort определяет динамический диапазон портов .
Итак, если я заставлю конечную точку использовать определенный порт, например
Тогда я могу открыть более 64K сокетов одновременно в системе.
В своем примере кода вы звоните Bind(bindEndpoint) , но не показываете, как bindEndpoint определено. Проверьте это:
- Ваша система фактически имеет несколько IP-адресов (обратная связь не учитывается)
- Вы фактически устанавливаете IP-адрес конечной точки на IP-адрес (не на петлю)
- Связки распределяются по нескольким IP-адресам
Адрес обратной связи не считается, потому что многие системы обрабатывают его специально для целей маршрутизации и привязки. Таким образом, привязка к портам в кольцевом шлейфе может поглощать порты по всем адресам так же, как если бы вы привязывались к INADDR_ANY ( 0.0.0.0 )
TCP и UDP используют 16-разрядное целое число без знака для обозначения номера порта. Я не думаю, что какая-либо реализация в какой-либо операционной системе сможет открыть в лучшем случае более 65535 сокетов на связанный адрес. Кроме того, я не удивлюсь, если Windows не реализует полностью изолированные таблицы состояний для каждого адаптера или каждого связанного адреса, а использует глобальную таблицу состояний. В таком случае это будет ограничение сетевой архитектуры Windows вместо мягкого настраиваемого ограничения.
Максимальное количество открытых сокетов windows
Есть ли сабж в Windows? В частности, Win 2k Pro SP 4
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
| От: | Arsu |
Дата: | 18.12.04 13:51 | |
Оценка: |
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
А зачем тебе столько?!
| От: | HISH | http://m0riarty.ya.ru |
Дата: | 18.12.04 17:52 | ||
Оценка: |
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
A>А зачем тебе столько?!
Сервер я пишу для своей тулзы Вопрос не «зачем?», а «почему?»
| От: | NeuroVirus |
Дата: | 19.12.04 00:18 | |
Оценка: |
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
вот сейчас провел бесчеловечный эксперимент
Win2k pro, sp4, все последние фиксы с автоапдейта,
256 М памяти, права админа,
создалось
2,5 миллиона сокетов (просто в цикле создаю до ошибки)
правда после этого система встала в неприличную позу,
перестали запускаться приложения, IE перестал что-либо получать (страница недоступна)
перестали открываться новые окна у работающих приложений, свободная память упала
практически до нуля.
в общем системе было явно плохо, причем всем сразу.
при закрытии приложения system idle process подчищал за ним минут пять, стало все хорошо.
какие делаем выводы? хэндлы (в том числе и сокеты) — общий системный ресурс
и система никого не ограничивает в свей «наглости» (ну по крайней мере с правами админа)
в вашем случае возможно либо какое то ограничение (коего я не знаю)
либо слишком много ресурсов уже выбрано на момент создания сокетов
(например уже запустили много приложений и еще на каждый свой сокет открываете по 15 файлов и 10 событий
| От: | adontz | http://adontz.wordpress.com/ |
Дата: | 19.12.04 13:09 | ||
Оценка: | -1 |
2,5 миллиона сокетов (просто в цикле создаю до ошибки)
Просто вызываешь socket? А подключить его куда-нибудь?
Чисто теоретически работающих сокетов не может быть больше чем 65536, по числу портов (которых и входящих и исходящих ровно столько). У меня реально оказалось создать только 2х50000 (50000 входящих и ещё 50000 подключённых к ним) сокетов.
| От: | IGor_79 |
Дата: | 20.12.04 07:33 | |
Оценка: |
2,5 миллиона сокетов (просто в цикле создаю до ошибки)
A>Просто вызываешь socket? А подключить его куда-нибудь?
A>Чисто теоретически работающих сокетов не может быть больше чем 65536, по числу портов (которых и входящих и исходящих ровно столько). У меня реально оказалось создать только 2х50000 (50000 входящих и ещё 50000 подключённых к ним) сокетов.
Исходя из вашей логики сервер не может принять больше
50000 входящих соединений.
Каждое соединение определяется следующими числами: Server IP:port, Client IP:port.
Т.о. теоретически сокетов может быть дофига и больше.
| От: | butcher | http://bu7cher.blogspot.com |
Дата: | 20.12.04 08:03 | ||
Оценка: |
Здравствуйте, adontz, Вы писали:
A>Чисто теоретически работающих сокетов не может быть больше чем 65536, по числу портов (которых и входящих и исходящих ровно столько). У меня реально оказалось создать только 2х50000 (50000 входящих и ещё 50000 подключённых к ним) сокетов.
очень легко можно привязать несколько сокетов к одному порту, см. про SO_REUSEADDR.
А вообще, сокеты могут быть не только TCP/IP, а например IPX, там уже другие порты. Ещё есть IrDA, Bluetooh.
До 2-ой версии Winsock кол-во сокетов можно было узнать через WSAStartup. Во второй же версии «The maximum number of sockets supported by a particular Windows Sockets service provider is implementation specific.» Ещё здесь немного сказано..
| От: | adontz | http://adontz.wordpress.com/ |
Дата: | 20.12.04 12:21 | ||
Оценка: |
50000 входящих соединений.
Я говорю о практике. Я на Windows Server 2003 Enterprise тестировал, причём сетевые сервисы не были активированы (никаких других подключений по сети, кроме десятка loopback’ов некоторых программ). Куда уж круче?
IG_>Каждое соединение определяется следующими числами: Server IP:port, Client IP:port.
IG_>Т.о. теоретически сокетов может быть дофига и больше.
В том-то всё и дело, что теоретически. Да, я согласен 2*32 + 2*16 = 96, итого до 79228162514264337593543950336 подключений И про SO_REUSEADDR я знаю, но на практике
50000 это неоднократно подтверждённый предел. В реальности, на 100МБит соединее сервер больше 10-20 тыс активных (keep-alive) соединений уже обычно не выдерживает.
| От: | zelyony |
Дата: | 20.12.04 13:07 | |
Оценка: | 26 (2) |
5000
создать больше сокетов можно указывая порт явно
ПС
возможно, что это только под Вынь
возможно, что верхний лимит регулируется какими-то настройками
«HISH» wrote in message
> Есть ли сабж в Windows? В частности, Win 2k Pro SP 4
>
> При открытии
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
| От: | Аноним |
Дата: | 20.12.04 13:13 | |
Оценка: |
5000
Z>создать больше сокетов можно указывая порт явно
Z>ПС
Z>возможно, что это только под Вынь
Z>возможно, что верхний лимит регулируется какими-то настройками
Z>»HISH» wrote in message
>> Есть ли сабж в Windows? В частности, Win 2k Pro SP 4
>>
>> При открытии
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
Во! Свежая мысль! Об этом я как-то не подумал, так как не было сказано как товарисч эти сокеты создавал.
Действительно, если явно биндить к нулевому порту или не биндить (а делать тучу клиентских коннектов)
то система должна выбрать порт из пула динамических. А их как раз около 4000 т.е. 5000-1024.
| От: | MaximE |
Дата: | 21.12.04 07:52 | |
Оценка: |
adontz wrote:
> Чисто теоретически работающих сокетов не может быть больше чем 65536, по числу портов (которых и входящих и исходящих ровно столько). У меня реально оказалось создать только 2х50000 (50000 входящих и ещё 50000 подключённых к ним) сокетов.
Только для конкретного протокола. Ты можешь, к примеру, одновременно слушать TCP и UDP сокет на одном и том же порту. В IP сегменте явно задан протокол, что позволяет использовать один и тот же порт одновременно несколькими (транспортными) протоколами.
| От: | HISH | http://m0riarty.ya.ru |
Дата: | 21.12.04 11:53 | ||
Оценка: |
5000
Z>>создать больше сокетов можно указывая порт явно
Z>>ПС
Z>>возможно, что это только под Вынь
Z>>возможно, что верхний лимит регулируется какими-то настройками
Z>>»HISH» wrote in message
>>> Есть ли сабж в Windows? В частности, Win 2k Pro SP 4
>>>
>>> При открытии
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
А>Во! Свежая мысль! Об этом я как-то не подумал, так как не было сказано как товарисч эти сокеты создавал.
А>Действительно, если явно биндить к нулевому порту или не биндить (а делать тучу клиентских коннектов)
А>то система должна выбрать порт из пула динамических. А их как раз около 4000 т.е. 5000-1024.
Э. То есть если я создаю сокет, коннекчусь к какому-нибудь сервису на порт. ну, скажем, 10000, то можно будет создать только 4000 _исходящих_ сокетов, потому что «пул динамических сокетов» на портах 1024 — 5000? А как мне (это уже просто интересно сделать большее количество исходящих соединений?
| От: | NeuroVirus |
Дата: | 21.12.04 12:09 | |
Оценка: |
5000
Z>>>создать больше сокетов можно указывая порт явно
Z>>>ПС
Z>>>возможно, что это только под Вынь
Z>>>возможно, что верхний лимит регулируется какими-то настройками
Z>>>»HISH» wrote in message
>>>> Есть ли сабж в Windows? В частности, Win 2k Pro SP 4
>>>>
>>>> При открытии
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
А>>Во! Свежая мысль! Об этом я как-то не подумал, так как не было сказано как товарисч эти сокеты создавал.
А>>Действительно, если явно биндить к нулевому порту или не биндить (а делать тучу клиентских коннектов)
А>>то система должна выбрать порт из пула динамических. А их как раз около 4000 т.е. 5000-1024.
HIS> Э. То есть если я создаю сокет, коннекчусь к какому-нибудь сервису на порт. ну, скажем, 10000, то можно будет создать только 4000 _исходящих_ сокетов, потому что «пул динамических сокетов» на портах 1024 — 5000? А как мне (это уже просто интересно сделать большее количество исходящих соединений?
честно говоря небыло надобности, навскидку могу предложить вручную биндить сокеты,
т.е. если bind() прошел с ошибкой «адрес занят» то порт := порт + 1 и опять.
только все равно, более 64,5 тыс. не выйдет
(начинать надо с 1025-ого порта, а лучше с 5001, чтоб виндам что-то осталось)
| От: | HISH | http://m0riarty.ya.ru |
Дата: | 21.12.04 12:20 | ||
Оценка: |
5000
Z>>>>создать больше сокетов можно указывая порт явно
Z>>>>ПС
Z>>>>возможно, что это только под Вынь
Z>>>>возможно, что верхний лимит регулируется какими-то настройками
Z>>>>»HISH» wrote in message
>>>>> Есть ли сабж в Windows? В частности, Win 2k Pro SP 4
>>>>>
>>>>> При открытии
4000 сокетов новые создавать не удается. Вопрос в том, из-за чего. 1) машина глючная; 2) ограничение винды; 3) ваш вариант
А>>>Во! Свежая мысль! Об этом я как-то не подумал, так как не было сказано как товарисч эти сокеты создавал.
А>>>Действительно, если явно биндить к нулевому порту или не биндить (а делать тучу клиентских коннектов)
А>>>то система должна выбрать порт из пула динамических. А их как раз около 4000 т.е. 5000-1024.
HIS>> Э. То есть если я создаю сокет, коннекчусь к какому-нибудь сервису на порт. ну, скажем, 10000, то можно будет создать только 4000 _исходящих_ сокетов, потому что «пул динамических сокетов» на портах 1024 — 5000? А как мне (это уже просто интересно сделать большее количество исходящих соединений?
NV>честно говоря небыло надобности, навскидку могу предложить вручную биндить сокеты,
NV>т.е. если bind() прошел с ошибкой «адрес занят» то порт := порт + 1 и опять.
NV>только все равно, более 64,5 тыс. не выйдет
NV>(начинать надо с 1025-ого порта, а лучше с 5001, чтоб виндам что-то осталось)
С bind()’ом все в порядке. Биндюс на открытый порт, все ок (мне ж только один раз надо забиндиться). Как я понял, сокет не получается создать когда я на клиенте говорю connect() — сокет же вс равно какому-то порту соответствовать должен. А вот диапазон этих портов при connect() от 1024 до 5000 (я так понял . Вот поэтому и не получается у меня больше 4000 сокетов создать.
| От: | NeuroVirus |
Дата: | 21.12.04 12:33 | |
Оценка: | 4 (1) |
Здравствуйте, HISH, Вы писали:
HIS> С bind()’ом все в порядке. Биндюс на открытый порт, все ок (мне ж только один раз надо забиндиться). Как я понял, сокет не получается создать когда я на клиенте говорю connect() — сокет же вс равно какому-то порту соответствовать должен. А вот диапазон этих портов при connect() от 1024 до 5000 (я так понял . Вот поэтому и не получается у меня больше 4000 сокетов создать.
Чего-то я не понял.
Как можно на открытый порт сделать bind() ?
Мы о клиентах говорим или серверах?
сервер:
socket()
bind()
listen()
accept()
клиент:
socket()
bind() — опционально
connect()
так вот если в bind указать нулевой порт, то он возьмется из динамического пула,
также и при коннекте без bind() — он сделает bind() автоматически с нулевым портом
итак, разжевываем на паскале для случая с клиентом.
| От: | HISH | http://m0riarty.ya.ru |
Дата: | 21.12.04 13:50 | ||
Оценка: |
Здравствуйте, NeuroVirus, Вы писали:
NV>Здравствуйте, HISH, Вы писали:
HIS>> С bind()’ом все в порядке. Биндюс на открытый порт, все ок (мне ж только один раз надо забиндиться). Как я понял, сокет не получается создать когда я на клиенте говорю connect() — сокет же вс равно какому-то порту соответствовать должен. А вот диапазон этих портов при connect() от 1024 до 5000 (я так понял . Вот поэтому и не получается у меня больше 4000 сокетов создать.
NV>Чего-то я не понял.
NV>Как можно на открытый порт сделать bind() ?
NV>Мы о клиентах говорим или серверах?
NV>цепочка действий
NV>сервер:
NV>socket()
NV>bind()
NV>listen()
NV>accept()
NV>клиент:
NV>socket()
NV>bind() — опционально
NV>connect()
NV>так вот если в bind указать нулевой порт, то он возьмется из динамического пула,
NV>также и при коннекте без bind() — он сделает bind() автоматически с нулевым портом
ага. все, спасибо Я про «bind() — опционально» и «если в bind указать нулевой порт, то он возьмется из динамического пула, также и при коннекте без bind() — он сделает bind() автоматически с нулевым портом» не знал.
| От: | Evil_Genius |
Дата: | 30.11.05 09:55 | |
Оценка: |
| От: | ToShAz |
Дата: | 30.11.05 10:20 | |
Оценка: |
Hello Evil_Genius,
> Товарищи, подскажите плиз, как в своей программе узнать количество
> входящих/исходящих соиденение в данный момент времени.
Принадлежащих твоей программе ? Или вообще во всей системе ?