GNU/Linux >> Znalost Linux >  >> Linux

Linux, sockety, neblokovací připojení

Pro asynchronní připojení byste měli použít následující kroky:

  • vytvořte soket pomocí socket(..., SOCK_NONBLOCK, ...)
  • zahájit připojení s connect(fd, ...)
  • pokud návratová hodnota není ani 0 ani EINPROGRESS , poté přerušit s chybou
  • počkejte do fd je signalizováno jako připraveno k výstupu
  • zkontrolujte stav soketu pomocí getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
  • hotovo

Žádné smyčky – pokud nechcete zpracovat EINTR .

Pokud je klient spuštěn jako první, měla by se zobrazit chyba ECONNREFUSED v posledním kroku. Pokud k tomu dojde, zavřete zásuvku a začněte od začátku.

Je těžké říct, co je s vaším kódem špatně, aniž byste viděli další podrobnosti. Předpokládám, že při chybách ve vašem check_socket nepřerušíte operace.


Existuje několik způsobů, jak otestovat, zda je neblokující připojení úspěšné.

  1. nejprve zavolejte getpeername(), pokud selže s chybou ENOTCONN, spojení se nezdařilo. pak zavolejte getockopt s SO_ERROR, abyste získali čekající chybu na soket
  2. volání čtení s délkou 0. pokud se čtení nezdařilo, spojení selhalo a errno for read indikuje, proč se spojení nezdařilo; read vrátí 0, pokud je připojení úspěšné
  3. zavolejte znovu a připojte se; pokud je errno EISCONN, připojení je již připojeno a první připojení bylo úspěšné.

Ref:UNIX Network Programming V1


D. J. Bernstein shromáždil různé metody, jak zkontrolovat, zda je asynchronní connect() hovor byl úspěšný nebo ne. Mnoho z těchto metod má na určitých systémech nevýhody, takže psaní přenosného kódu pro ně je neočekávaně obtížné. Pokud si někdo chce přečíst všechny možné metody a jejich nevýhody, podívejte se na tento dokument.

Pro ty, kteří chtějí pouze verzi tl;dr, je nejpřenosnějším způsobem následující:

Jakmile systém signalizuje soket jako zapisovatelný, nejprve zavolejte getpeername() zjistit, zda se připojil nebo ne. Pokud bylo volání úspěšné, zásuvka se připojila a můžete ji začít používat. Pokud toto volání selže s ENOTCONN , připojení se nezdařilo. Chcete-li zjistit, proč to selhalo, zkuste přečíst jeden bajt ze soketu read(fd, &ch, 1) , což také selže, ale chyba, kterou dostanete, je chyba, kterou byste dostali z connect() kdyby to nebylo neblokující.


Linux
  1. Meziprocesová komunikace v Linuxu:Sokety a signály

  2. Je alokace paměti v linuxu neblokující?

  3. Jak na to Linux pojmenované zásuvky

  1. Jak používat OpenSSH k připojení k vašemu linuxovému serveru

  2. Připojte se k serveru pomocí SSH v systému Linux nebo Mac OS X

  3. Fork vs Clone na 2.6 Kernel Linuxu

  1. Jak děláte neblokující I/O konzoly na Linuxu v C?

  2. Zkontrolujte připojení otevřené nebo zavřené? (v C v Linuxu)

  3. Linux API k určení soketů vlastněných procesem