Portál AbcLinuxu, 12. května 2025 07:41

Dotaz: Linux/Win32 API: SO_LINGER - okamžité uzavření soketu

Fuky avatar 30.10.2008 22:55 Fuky | skóre: 52 | blog: 4u
Linux/Win32 API: SO_LINGER - okamžité uzavření soketu
Přečteno: 396×
Odpovědět | Admin
Multiplatformní aplikace napsaná v C se připojí k protistraně a začne jí posílat data. Protistraně se zaplní buffer, takže přestane přijímat pakety. Začnou se tedy objevovat retransmission pakety. Uzavřu tedy spojení s protistranou, abych jí dal čas na vyprázdnění bufferu. V Linuxu se mi spojení díky nastavení SO_LINGER okamžitě uzavře. Ovšem ve Windows spojení zůstane viset dál, i když použiju stejné nastavení SO_LINGER, protože se čeká na doručení paketu. Jak zajistit i ve Windows okamžité uzavření soketu, i když jsou ve frontě stále nějaké nedoručené pakety? Děkuji za nakopnutí správným směrem.
-- RÁMO: psí tábor , ETriatlon: Výuka plavání

Řešení dotazu:


Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Pavel Stárek avatar 31.10.2008 12:16 Pavel Stárek | skóre: 44 | blog: Tady bloguju já :-) | Kolín
Rozbalit Rozbalit vše Re: Linux/Win32 API: SO_LINGER - okamžité uzavření soketu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Citace z dokumentace na webu MSDN:

To disable a socket from remaining open, an application only needs to set the l_onoff member of the linger structure to zero.

A pro jistotu bych ještě nastavil ten l_linger timeout v té struktuře na nulu.
Kdo chce, hledá způsob; kdo nechce, hledá důvod.
Fuky avatar 2.11.2008 12:00 Fuky | skóre: 52 | blog: 4u
Rozbalit Rozbalit vše Re: Linux/Win32 API: SO_LINGER - okamžité uzavření soketu
Děkuji za radu, i toto nastavení jsem zkoušel a výsledek je stále stejný. Jakmile začnou chodit retransmission pakety, tak mi vrátí fce select() na zapisovacím deskriptoru WSAEWOULDBLOCK - Error 10035, já tedy uzavřu soket, ale Windows nechá spojení otevřené a čeká až bude moci doručit neodeslaný paket.
Fuky avatar 2.11.2008 22:33 Fuky | skóre: 52 | blog: 4u
Rozbalit Rozbalit vše Re: Linux/Win32 API: SO_LINGER - okamžité uzavření soketu

Správně je set_linger.l_onoff = 1; set_linger.l_linger = 0;, tj. zahodí neodeslaná data a okamžitě odešlě protistraně RESET. Pokud je l_onoff == 0 pošle FIN, ale pouze pokud jsou všechna data doručena protistraně (implicitní chování). Pokud je l_onoff == 1 && l_linger != 0, tak v případě, že jsou všechna data doručena pošle FIN, jinak po vypršení timeoutu pošlě RESET.

Pokud program spustím pod Wine, funguje dle očekávání bez problémů. Ovšem na Windows ne...

Stejný dotaz jsem ještě položil na Okamžité uzavření soketu ve Windows (builder.cz), ovšem zatím bez řešení.

Řešení 1× (Fuky (tazatel))
Fuky avatar 3.11.2008 22:52 Fuky | skóre: 52 | blog: 4u
Rozbalit Rozbalit vše Re: Linux/Win32 API: SO_LINGER - okamžité uzavření soketu
Takže problém je vyřešen. Chyba bude nakonec na straně FW protistrany v nižší síťové vrstvě, na funkci v Linuxu to nemělo vliv, ale ve Windows nefungovalo okamžité uzavření soketu. Další problém byl v tom, že před closesocket() se nesmí volat shutdown() jinak se soket také okamžitě neuzavře.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.