GNU/Linux >> Znalost Linux >  >> Linux

Jak se liší SO_REUSEADDR a SO_REUSEPORT?

Vítejte v nádherném světě přenositelnosti... nebo spíše jejího nedostatku. Než začneme tyto dvě možnosti podrobně analyzovat a podíváme se hlouběji na to, jak s nimi nakládají různé operační systémy, je třeba poznamenat, že implementace BSD socketu je matkou všech implementací socketů. V podstatě všechny ostatní systémy v určitém okamžiku zkopírovaly implementaci soketu BSD (nebo alespoň jeho rozhraní) a poté jej začaly vyvíjet samy. Implementace BSD socketu se samozřejmě vyvíjela také ve stejnou dobu, a tak systémy, které ji zkopírovaly později, získaly funkce, které v systémech, které ji zkopírovaly dříve, chyběly. Pochopení implementace soketu BSD je klíčem k pochopení všech ostatních implementací soketu, takže byste si o tom měli přečíst, i když vás nezajímá psát kód pro systém BSD.

Než se podíváme na tyto dvě možnosti, měli byste vědět několik základních věcí. Připojení TCP/UDP je identifikováno n-ticí pěti hodnot:

{<protocol>, <src addr>, <src port>, <dest addr>, <dest port>}

Jakákoli jedinečná kombinace těchto hodnot identifikuje spojení. Výsledkem je, že žádná dvě spojení nemohou mít stejných pět hodnot, jinak by systém již nebyl schopen tato spojení rozlišit.

Protokol soketu je nastaven, když je soket vytvořen pomocí socket() funkce. Zdrojová adresa a port se nastavují pomocí bind() funkce. Cílová adresa a port se nastavují pomocí connect() funkce. Protože UDP je protokol bez připojení, lze zásuvky UDP používat i bez jejich připojení. Přesto je možné je propojit a v některých případech velmi výhodné pro váš kód a obecný návrh aplikace. V režimu bez připojení jsou sokety UDP, které nebyly explicitně svázány, když jsou přes ně poprvé odeslána data, obvykle automaticky svázány systémem, protože nesvázaný soket UDP nemůže přijímat žádná (odpovědní) data. Totéž platí pro nevázaný TCP soket, je automaticky svázán předtím, než bude připojen.

Pokud explicitně svážete soket, je možné jej svázat s portem 0 , což znamená „jakýkoli port“. Vzhledem k tomu, že socket nemůže být skutečně vázán na všechny existující porty, bude si systém muset v takovém případě vybrat konkrétní port sám (obvykle z předdefinovaného, ​​OS specifického rozsahu zdrojových portů). Podobný zástupný znak existuje pro zdrojovou adresu, kterou může být „libovolná adresa“ (0.0.0.0 v případě IPv4 a :: v případě IPv6). Na rozdíl od portů může být socket skutečně vázán na "libovolnou adresu", což znamená "všechny zdrojové IP adresy všech lokálních rozhraní". Pokud je zásuvka připojena později, systém musí zvolit konkrétní zdrojovou IP adresu, protože zásuvku nelze připojit a zároveň být vázána na jakoukoli lokální IP adresu. V závislosti na cílové adrese a obsahu směrovací tabulky systém vybere vhodnou zdrojovou adresu a nahradí „libovolnou“ vazbu vazbou na vybranou zdrojovou IP adresu.

Ve výchozím nastavení nemohou být žádné dva sokety vázány na stejnou kombinaci zdrojové adresy a zdrojového portu. Dokud je zdrojový port jiný, je zdrojová adresa ve skutečnosti irelevantní. Vazba socketA na ipA:portA a socketB na ipB:portB je vždy možné, pokud ipA != ipB platí, i když portA == portB . Např. socketA patří k programu serveru FTP a je vázán na 192.168.0.1:21 a socketB patří k jinému programu FTP serveru a je vázán na 10.0.0.1:21 , obě vazby budou úspěšné. Mějte však na paměti, že soket může být lokálně vázán na „libovolnou adresu“. Pokud je soket vázán na 0.0.0.0:21 , je svázán se všemi existujícími lokálními adresami současně a v takovém případě nemůže být žádný další soket svázán s portem 21 , bez ohledu na to, ke které konkrétní IP adrese se pokusí navázat, jako 0.0.0.0 koliduje se všemi existujícími místními IP adresami.

Vše, co bylo dosud řečeno, je téměř stejné pro všechny hlavní operační systémy. Věci začnou být specifické pro OS, když do hry vstoupí opětovné použití adresy. Začínáme s BSD, protože jak jsem řekl výše, je to matka všech implementací socketů.

BSD

SO_REUSEADDR

Pokud SO_REUSEADDR je povolena na soketu před jeho vázáním, lze soket úspěšně svázat, pokud nedojde ke konfliktu s jiným soketem vázaným přesně stejnou kombinaci zdrojové adresy a portu. Možná se teď ptáte, jak je to jiné než dříve? Klíčové slovo je „přesně“. SO_REUSEADDR hlavně mění způsob, jakým se při hledání konfliktů zachází s adresami se zástupnými znaky („jakákoli IP adresa“).

Bez SO_REUSEADDR , vazba socketA na 0.0.0.0:21 a poté svázáním socketB na 192.168.0.1:21 selže (s chybou EADDRINUSE ), protože 0.0.0.0 znamená "libovolná místní IP adresa", takže všechny místní IP adresy jsou považovány za používané tímto soketem, a to včetně 192.168.0.1 , také. S SO_REUSEADDR bude to úspěšné, protože 0.0.0.0 a 192.168.0.1 nejsou přesně stejná adresa, jedna je zástupný znak pro všechny místní adresy a druhá je velmi specifická místní adresa. Všimněte si, že výše uvedené tvrzení platí bez ohledu na to, v jakém pořadí socketA a socketB jsou svázáni; bez SO_REUSEADDR vždy selže, s SO_REUSEADDR vždy se to podaří.

Pro lepší přehled si zde udělejme tabulku a uveďme všechny možné kombinace:

SO_REUSEADDR       socketA        socketB       Result
---------------------------------------------------------------------
  ON/OFF       192.168.0.1:21   192.168.0.1:21    Error (EADDRINUSE)
  ON/OFF       192.168.0.1:21      10.0.0.1:21    OK
  ON/OFF          10.0.0.1:21   192.168.0.1:21    OK
   OFF             0.0.0.0:21   192.168.1.0:21    Error (EADDRINUSE)
   OFF         192.168.1.0:21       0.0.0.0:21    Error (EADDRINUSE)
   ON              0.0.0.0:21   192.168.1.0:21    OK
   ON          192.168.1.0:21       0.0.0.0:21    OK
  ON/OFF           0.0.0.0:21       0.0.0.0:21    Error (EADDRINUSE)

Výše uvedená tabulka předpokládá, že socketA již bylo úspěšně svázáno s adresou zadanou pro socketA a poté socketB je vytvořen, buď získá SO_REUSEADDR set nebo ne, a nakonec je vázán na adresu uvedenou pro socketB . Result je výsledkem operace vazby pro socketB . Pokud první sloupec říká ON/OFF , hodnota SO_REUSEADDR je pro výsledek irelevantní.

Dobře, SO_REUSEADDR má vliv na adresy se zástupnými znaky, dobré vědět. To však není jediný účinek, který má. Existuje další dobře známý efekt, který je také důvodem, proč většina lidí používá SO_REUSEADDR v serverových programech na prvním místě. Pro další důležité použití této možnosti se musíme hlouběji podívat na to, jak protokol TCP funguje.

Pokud je soket TCP zavírán, obvykle se provádí 3-cestný handshake; sekvence se nazývá FIN-ACK . Problém je v tom, že poslední ACK této sekvence může na druhé straně dorazit nebo nedorazil a pouze pokud ano, druhá strana také považuje socket za plně uzavřený. Aby se zabránilo opětovnému použití kombinace adresa+port, kterou mohou někteří vzdálení peer stále považovat za otevřenou, nebude systém po odeslání posledního ACK okamžitě považovat soket za mrtvý. ale místo toho uveďte soket do stavu běžně označovaného jako TIME_WAIT . V tomto stavu může být několik minut (nastavení v závislosti na systému). Na většině systémů můžete tento stav obejít povolením prodlevy a nastavením doby prodlevy na nulu1, ale neexistuje žádná záruka, že je to vždy možné, že systém vždy vyhoví tomuto požadavku, a i když jej systém vyhoví, způsobí to zásuvka, která má být uzavřena resetem (RST ), což není vždy skvělý nápad. Chcete-li se dozvědět více o prodlení, podívejte se na mou odpověď na toto téma.

Otázkou je, jak systém zachází se socketem ve stavu TIME_WAIT ? Pokud SO_REUSEADDR není nastaven, soket ve stavu TIME_WAIT je považováno za stále vázáno na zdrojovou adresu a port a jakýkoli pokus o navázání nového soketu na stejnou adresu a port selže, dokud nebude soket skutečně uzavřen. Neočekávejte tedy, že zdrojovou adresu soketu můžete znovu svázat ihned po jeho zavření. Ve většině případů to selže. Pokud však SO_REUSEADDR je nastaven pro soket, který se pokoušíte svázat, jiný soket svázaný se stejnou adresou a portem ve stavu TIME_WAIT je jednoduše ignorován, koneckonců je již „napůl mrtvý“ a váš socket se může bez problému vázat na přesně stejnou adresu. V tom případě nehraje žádnou roli, že druhý socket může mít přesně stejnou adresu a port. Všimněte si, že navázání soketu na přesně stejnou adresu a port jako umírající soket v TIME_WAIT stav může mít neočekávané a obvykle nežádoucí vedlejší účinky v případě, že druhá zásuvka je stále "v provozu", ale to je nad rámec této odpovědi a naštěstí jsou tyto vedlejší účinky v praxi spíše vzácné.

Je tu jedna poslední věc, kterou byste měli vědět o SO_REUSEADDR . Vše napsané výše bude fungovat, pokud má soket, ke kterému se chcete připojit, povoleno opakované použití adresy. Není nutné, aby druhý soket, ten, který je již svázán nebo je v TIME_WAIT stát, také měl tento příznak nastaven, když byl vázán. Kód, který rozhoduje, zda bude vazba úspěšná nebo selže, pouze kontroluje SO_REUSEADDR příznak zásuvky vložený do bind() volání, u všech ostatních kontrolovaných soketů se na tento příznak ani nehledí.

SO_REUSEPORT

SO_REUSEPORT je to, co by většina lidí očekávala SO_REUSEADDR být. V podstatě SO_REUSEPORT umožňuje svázat libovolný počet soketů na přesně stejnou zdrojovou adresu a port, pokud všechny předchozí vázané sokety měly také SO_REUSEPORT nastaveny před tím, než byly svázány. Pokud první soket, který je vázán na adresu a port, nemá SO_REUSEPORT nastaven, žádný jiný soket nemůže být svázán s přesně stejnou adresou a portem, bez ohledu na to, zda má tento druhý soket SO_REUSEPORT nastavit nebo ne, dokud první zásuvka opět neuvolní svou vazbu. Na rozdíl od případu SO_REUESADDR kód zpracovávající SO_REUSEPORT nejen ověří, že aktuálně vázaný soket má SO_REUSEPORT set, ale také ověří, že soket s konfliktní adresou a portem měl SO_REUSEPORT nastaveno, když bylo svázáno.

SO_REUSEPORT neznamená SO_REUSEADDR . To znamená, pokud zásuvka neměla SO_REUSEPORT nastaven, když byl svázán a jiný soket má SO_REUSEPORT nastaven, když je vázán na přesně stejnou adresu a port, vazba selže, což se očekává, ale také se nezdaří, pokud druhý soket již umírá a je v TIME_WAIT Stát. Aby bylo možné svázat soket se stejnými adresami a portem jako jiný soket v TIME_WAIT stav vyžaduje buď SO_REUSEADDR nastavit na této zásuvce nebo SO_REUSEPORT musí být nastaveno na obou zásuvky před jejich spojením. Samozřejmě je možné nastavit obojí, SO_REUSEPORT a SO_REUSEADDR , na zásuvce.

O SO_REUSEPORT toho není moc co říci kromě toho byl přidán později než SO_REUSEADDR , to je důvod, proč jej nenajdete v mnoha implementacích soketů jiných systémů, které "forkovaly" kód BSD před přidáním této možnosti, a že před tímto neexistoval způsob, jak spojit dva sokety s přesně stejnou adresou soketu v BSD možnost.

Connect() vrací EADDRINUSE?

Většina lidí ví, že bind() může selhat s chybou EADDRINUSE když si však začnete hrát s opětovným použitím adresy, můžete se dostat do podivné situace, že connect() selže i s touto chybou. Jak to může být? Jak může být vzdálená adresa, po tom všem, co connect přidává do soketu, již používána? Připojení více zásuvek k přesně stejné vzdálené adrese nikdy předtím nebyl problém, takže co je tady špatně?

Jak jsem řekl úplně nahoře ve své odpovědi, spojení je definováno n-ticí pěti hodnot, vzpomínáte? A také jsem řekl, že těchto pět hodnot musí být jedinečných, jinak systém už nedokáže rozlišit dvě spojení, že? Díky opětovnému použití adresy můžete svázat dva sokety stejného protokolu se stejnou zdrojovou adresou a portem. To znamená, že tři z těchto pěti hodnot jsou již pro tyto dva sokety stejné. Pokud se nyní pokusíte připojit oba tyto sokety také na stejnou cílovou adresu a port, vytvoříte dva spojené sokety, jejichž n-tice jsou naprosto identické. To nemůže fungovat, alespoň ne pro TCP spojení (UDP spojení stejně nejsou žádná skutečná spojení). Pokud data dorazila pro jedno ze dvou připojení, systém nedokázal určit, ke kterému připojení data patří. Alespoň cílová adresa nebo cílový port musí být pro každé připojení odlišné, aby systém neměl problém identifikovat, ke kterému připojení příchozí data patří.

Pokud tedy svážete dva sokety stejného protokolu se stejnou zdrojovou adresou a portem a pokusíte se je oba připojit ke stejné cílové adrese a portu, connect() ve skutečnosti selže s chybou EADDRINUSE pro druhou zásuvku, kterou se pokoušíte připojit, což znamená, že zásuvka s identickou n-ticí pěti hodnot je již připojena.

Adresy vícesměrového vysílání

Většina lidí ignoruje skutečnost, že multicastové adresy existují, ale existují. Zatímco unicastové adresy se používají pro komunikaci jeden ku jedné, multicastové adresy se používají pro komunikaci 1 ku mnoha. Většina lidí se dozvěděla o multicastových adresách, když se dozvěděli o IPv6, ale multicastové adresy existovaly také v IPv4, i když tato funkce nebyla na veřejném internetu nikdy široce používána.

Význam SO_REUSEADDR změny pro adresy vícesměrového vysílání, protože umožňuje, aby bylo více soketů svázáno s přesně stejnou kombinací zdrojové adresy vícesměrového vysílání a portu. Jinými slovy, pro vícesměrové adresy SO_REUSEADDR chová se přesně jako SO_REUSEPORT pro unicast adresy. Ve skutečnosti kód zpracovává SO_REUSEADDR a SO_REUSEPORT identicky pro vícesměrové adresy, to znamená, že byste mohli říci, že SO_REUSEADDR znamená SO_REUSEPORT pro všechny multicastové adresy a naopak.


FreeBSD/OpenBSD/NetBSD

To vše jsou poněkud pozdní forky původního kódu BSD, proto všechny tři nabízejí stejné možnosti jako BSD a také se chovají stejně jako v BSD.


macOS (MacOS X)

Ve svém jádru je macOS jednoduše UNIX ve stylu BSD s názvem „Darwin “, založený na poměrně pozdním rozvětvení kódu BSD (BSD 4.3), který byl později dokonce znovu synchronizován s (v té době aktuální) kódovou základnou FreeBSD 5 pro vydání Mac OS 10.3, takže Apple mohl získat plná kompatibilita s POSIX (macOS má certifikaci POSIX). Navzdory tomu, že jeho jádrem je mikrojádro ("Mach "), zbytek jádra ("XNU ") je v podstatě jen jádro BSD, a proto macOS nabízí stejné možnosti jako BSD a také se chovají stejně jako v BSD.

iOS / watchOS / tvOS

iOS je jen macOS fork s mírně upraveným a ořezaným jádrem, poněkud okleštěnou sadou nástrojů pro uživatelský prostor a mírně odlišnou výchozí sadou rámců. watchOS a tvOS jsou iOS forky, které jsou ještě dále zkráceny (zejména watchOS). Podle mého nejlepšího vědomí se všechny chovají přesně jako macOS.


Linux

Linux <3.9

Před Linuxem 3.9 pouze možnost SO_REUSEADDR existoval. Tato volba se chová obecně stejně jako v BSD se dvěma důležitými výjimkami:

  1. Dokud je naslouchající (serverový) soket TCP vázán na konkrétní port, SO_REUSEADDR možnost je zcela ignorována pro všechny sokety zaměřené na tento port. Navázání druhého soketu na stejný port je možné pouze tehdy, pokud to bylo možné také v BSD bez SO_REUSEADDR soubor. Např. nemůžete se vázat na zástupnou adresu a poté na konkrétnější nebo naopak, obojí je možné v BSD, pokud nastavíte SO_REUSEADDR . Co můžete udělat, je, že se můžete vázat na stejný port a dvě různé adresy bez zástupných znaků, protože to je vždy povoleno. V tomto ohledu je Linux restriktivnější než BSD.

  2. Druhou výjimkou je, že pro klientské sokety se tato volba chová přesně jako SO_REUSEPORT v BSD, pokud oba měli tento příznak nastaven před tím, než byli svázáni. Důvodem pro to bylo jednoduše to, že je důležité mít možnost svázat více soketů na přesně stejnou adresu soketu UDP pro různé protokoly a protože dříve neexistoval žádný SO_REUSEPORT před verzí 3.9 chování SO_REUSEADDR byl odpovídajícím způsobem změněn, aby tuto mezeru zaplnil. V tomto ohledu je Linux méně omezující než BSD.

Linux>=3.9

Linux 3.9 přidal možnost SO_REUSEPORT i na Linux. Tato volba se chová přesně jako volba v BSD a umožňuje vazbu na přesně stejnou adresu a číslo portu, pokud mají všechny sokety tuto volbu nastavenou před jejich navázáním.

Stále však existují dva rozdíly oproti SO_REUSEPORT na jiných systémech:

  1. Aby se zabránilo „ukradení portu“, existuje jedno speciální omezení:Všechny sokety, které chtějí sdílet stejnou adresu a kombinaci portů, musí patřit k procesům, které sdílejí stejné efektivní ID uživatele! Takže jeden uživatel nemůže "ukrást" porty jiného uživatele. Toto je nějaké speciální kouzlo, které trochu kompenzuje chybějící SO_EXCLBIND /SO_EXCLUSIVEADDRUSE příznaky.

  2. Kromě toho jádro provádí nějaké "zvláštní kouzlo" pro SO_REUSEPORT sokety, které se nenacházejí v jiných operačních systémech:U soketů UDP se snaží distribuovat datagramy rovnoměrně, u naslouchacích soketů TCP se pokouší distribuovat příchozí požadavky na připojení (ty, které jsou přijímány voláním accept() ) rovnoměrně napříč všemi sokety, které sdílejí stejnou kombinaci adres a portů. Aplikace tak může snadno otevřít stejný port ve více podřízených procesech a poté použít SO_REUSEPORT získat velmi levné vyrovnávání zátěže.


Android

I když se celý systém Android poněkud liší od většiny linuxových distribucí, v jádru funguje mírně upravené linuxové jádro, takže vše, co platí pro Linux, by mělo platit i pro Android.


Windows

Windows zná pouze SO_REUSEADDR možnost, není zde SO_REUSEPORT . Nastavení SO_REUSEADDR na socketu ve Windows se chová jako nastavení SO_REUSEPORT a SO_REUSEADDR na soketu v BSD, s jednou výjimkou:

Před Windows 2003, socket s SO_REUSEADDR mohl být vždy vázán na přesně stejnou zdrojovou adresu a port jako již vázaný soket, i když druhý soket neměl tuto možnost nastavenou, když byl vázán . Toto chování umožnilo aplikaci „ukrást“ připojený port jiné aplikace. Netřeba dodávat, že to má zásadní bezpečnostní důsledky!

Microsoft si to uvědomil a přidal další důležitou možnost soketu:SO_EXCLUSIVEADDRUSE . Nastavení SO_EXCLUSIVEADDRUSE na soketu zajišťuje, že pokud je vazba úspěšná, je kombinace zdrojové adresy a portu vlastněna výhradně tímto soketem a žádný jiný soket se na ně nemůže vázat, ani pokud má SO_REUSEADDR set.

Toto výchozí chování bylo změněno nejprve ve Windows 2003, Microsoft tomu říká "Enhanced Socket Security" (vtipný název pro chování, které je výchozí ve všech ostatních hlavních operačních systémech). Pro více podrobností stačí navštívit tuto stránku. Existují tři tabulky:První ukazuje klasické chování (stále se používá při použití režimů kompatibility!), druhá ukazuje chování Windows 2003 a vyšší, když bind() volání provádí stejný uživatel a třetí, když je bind() hovory uskutečňují různí uživatelé.


Solaris

Solaris je nástupcem SunOS. SunOS byl původně založen na vidlici BSD, SunOS 5 a později byl založen na vidlici SVR4, nicméně SVR4 je sloučením BSD, System V a Xenix, takže do určité míry je Solaris také vidlice BSD a spíše raný. Výsledkem je, že Solaris zná pouze SO_REUSEADDR , neexistuje žádný SO_REUSEPORT . SO_REUSEADDR chová se v podstatě stejně jako v BSD. Pokud vím, neexistuje způsob, jak dosáhnout stejného chování jako SO_REUSEPORT v Solaris, to znamená, že není možné svázat dva sokety s přesně stejnou adresou a portem.

Podobně jako Windows má Solaris možnost dát zásuvce exkluzivní vazbu. Tato volba se jmenuje SO_EXCLBIND . Pokud je tato možnost nastavena na soketu před jeho navázáním, nastavení SO_REUSEADDR na jiném soketu nemá žádný účinek, pokud jsou dva sokety testovány na konflikt adres. Např. pokud socketA je vázán na zástupnou adresu a socketBSO_REUSEADDR povoleno a je vázáno na jinou než zástupnou adresu a stejný port jako socketA , bude tato vazba normálně úspěšná, pokud není socketA měl SO_EXCLBIND povoleno, v takovém případě selže bez ohledu na SO_REUSEADDR vlajka socketB .


Jiné systémy

V případě, že váš systém není uveden výše, napsal jsem malý testovací program, pomocí kterého můžete zjistit, jak váš systém zvládá tyto dvě možnosti. Také pokud si myslíte, že mé výsledky jsou nesprávné , prosím nejprve spusťte tento program, než zveřejníte jakékoli komentáře a případně uvedete nepravdivá tvrzení.

Vše, co kód vyžaduje ke sestavení, je trochu POSIX API (pro síťové části) a kompilátor C99 (ve skutečnosti většina kompilátorů jiných než C99 bude fungovat dobře, pokud nabízí inttypes.h a stdbool.h; např. gcc podporoval oba dlouho předtím, než nabídl plnou podporu C99).

Vše, co program potřebuje ke spuštění, je, že alespoň jedno rozhraní ve vašem systému (jiné než lokální rozhraní) má přidělenou IP adresu a že je nastavena výchozí trasa, která toto rozhraní používá. Program shromáždí tuto IP adresu a použije ji jako druhou "specifickou adresu".

Testuje všechny možné kombinace, na které si vzpomenete:

  • Protokoly TCP a UDP
  • Normální sokety, naslouchací (serverové) sokety, multicastové sokety
  • SO_REUSEADDR nastavte na socket1, socket2 nebo oba sockety
  • SO_REUSEPORT nastavte na socket1, socket2 nebo oba sockety
  • Všechny kombinace adres, které můžete vytvořit z 0.0.0.0 (zástupný znak), 127.0.0.1 (konkrétní adresa) a druhá konkrétní adresa nalezená ve vašem primárním rozhraní (pro vícesměrové vysílání je to jen 224.1.2.3 ve všech testech)

a vytiskne výsledky v pěkné tabulce. Bude také fungovat na systémech, které neznají SO_REUSEPORT , v takovém případě tato možnost jednoduše není testována.

Co program nemůže snadno otestovat, je jak SO_REUSEADDR funguje na soketech v TIME_WAIT stavu, protože je velmi složité vynutit a udržet zásuvku v tomto stavu. Naštěstí se zdá, že většina operačních systémů se zde jednoduše chová jako BSD a většinu času mohou programátoři existenci tohoto stavu jednoduše ignorovat.

Zde je kód (nemohu ho sem zahrnout, odpovědi mají limit velikosti a kód by tuto odpověď posunul nad limit).


Meckiho odpověď je naprosto perfektní, ale stojí za to dodat, že FreeBSD také podporuje SO_REUSEPORT_LB , který napodobuje Linux' SO_REUSEPORT chování - vyrovnává zátěž; viz setsockopt(2)


Linux
  1. Jak spravovat a vypisovat služby v Linuxu

  2. Co je Podman a jak se liší od Dockeru?

  3. Jak na to:Replikace a konfigurace DRBD

  1. Jak odeberu připojení soketu CLOSE_WAIT

  2. Jak zvládnout reventy linuxového socketu POLLERR, POLLHUP a POLLNVAL?

  3. Jak se liší ulimit -n a /proc/sys/fs/file-max?

  1. Jak duální bootování Linuxu a Windows

  2. $bashpid a $$ se v některých případech liší?

  3. Jak na to:Programování soketů v Pythonu