Windows begrænsning på antal samtidige åbninger/tilslutninger pr. Maskine

Indlæg af Hanne Mølgaard Plasc

Problem



Lad os sige, at jeg har Windows 7 med en reel netværksinterface og få loopback-grænseflader.
Jeg har IOCP-aktiveret server, der accepterer forbindelser fra klienter.
Jeg forsøger at simulere så meget som muligt reelle klientforbindelser til serveren.


Min klientkode opretter simpelthen X antal stikforbindelser
(bemærk at klienten binder til en given grænseflade):


        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));
        }


På en loopback-grænseflade har jeg flere IP'er, som jeg bruger til binding.
Derudover bruger jeg også ægte grænseflade til at binde på.
Jeg løb ind i et problem, når antallet af åbne åbninger er omkring 64K pr. Maskine:


Uhåndteret undtagelse: System.Net.Sockets.SocketException: En operation i en stikkontakt kunne ikke udføres, fordi systemet manglede tilstrækkelig bufferplads eller fordi en kø var fuld


Jeg har prøvet flere hjælpeløse ting som:
- indstilling af MaxUserPort til maksimal værdi og nogle andre anbefalede TCPIP-indstillinger i registreringsdatabasen.
- forsøger at køre to servere på forskellige grænseflader (ægte grænseflader og loopback) og bruge flere klienter.


Er det en kendt begrænsning i Windows eller det er muligt at overvinde det på en eller anden måde?


Tak for hjælpen!

Bedste reference


Jeg har fundet på nogle Microsoft-sider, at:



  ... HKEY\_LOCAL\_MACHINESYSTEMCurrentControlSetServicesTcpipParametersMaxUserPort
  registreringsdatabasenes nøgle er defineret som den maksimale port op til, hvilke porte der kan tildeles for wildcard-binde. Værdien af ​​registreringsdatabasen MaxUserPort definerer det dynamiske portinterval ...



Så hvis jeg tvinge endepunktet til at bruge en bestemt port, f.eks.


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


Så kan jeg åbne mere end 64K samtidige stik i systemet.

Andre referencer 1


I dit kodeeksempel ringer du Bind(bindEndpoint), men du viser ikke, hvordan bindEndpoint er defineret. Kontroller at:



  • Dit system har faktisk flere IP-adresser (loopback tæller ikke)

  • Du angiver faktisk endepunktets IP-adresse til en IP-adresse (ikke loopback)

  • Bindene spredes over flere IP-adresser



Loopback-adressen tæller ikke, fordi mange systemer behandler det specielt til routing og bindingsformål. Så bindende til havne i loopback kan suger portene på tværs af alle adresser det samme som hvis du var bindende til INADDR\_ANY (0.0.0.0).

Andre referencer 2


Både TCP og UDP bruger et usigneret 16-biters heltal til at angive portnummer. Jeg forestiller mig ikke, at implementering i et hvilket som helst operativsystem vil kunne åbne mere end 65535 sockets pr. Bundet adresse i bedste fald. Desuden vil jeg ikke blive overrasket, hvis Windows ikke implementerer fuldt isolerede stat tabeller for hver adapter eller hver bundet adresse, men i stedet baserer sig på en global statsborde. Hvis det er tilfældet, ville det være en Windows-netværksarkitektur grænse i stedet for en blød, konfigurerbar grænse.