GNU/Linux >> Znalost Linux >  >> Linux

Proč by connect() dával EADDRNOTAVAIL?

Zkontrolujte tento odkaz

http://www.toptip.ca/2010/02/linux-eaddrnotavail-address-not.html

UPRAVIT :Ano, chtěl jsem přidat další, ale kvůli nouzi jsem to tam musel přerušit

Zavřeli jste zásuvku před pokusem o opětovné připojení? Zavření sdělí systému, že pár soketů (ip/port) je nyní volný.

Podívejte se také na další položky:

  • Pokud je místní port již připojen k dané vzdálené IP a portu (tj. již existuje identický pár soketů), zobrazí se tato chyba (viz odkaz na chybu níže).
  • Vazba adresy soketu, která není místní, způsobí tuto chybu. pokud jsou IP adresy počítače 127.0.0.1 a 1.2.3.4 a pokoušíte se navázat vazbu na 1.2.3.5, zobrazí se tato chyba.
  • EADDRNOTAVAIL:Zadaná adresa není na vzdáleném počítači k dispozici nebo pole adresy ve struktuře názvu obsahuje samé nuly.

Odkaz s chybou podobnou té vaší (odpověď je blízko dole)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294599

Zdá se, že váš soket je v podstatě zaseknutý v jednom z interních stavů TCP a že přidání zpoždění pro opětovné připojení by mohlo vyřešit váš problém, jak se zdá, v tomto hlášení o chybě.


Pokud nejste ochotni změnit počet dostupných dočasných portů (jak navrhuje David) nebo potřebujete více připojení, než je teoretické maximum, existují dvě další metody, jak snížit počet používaných portů. Do různé míry však porušují standard TCP, takže by se měly používat opatrně.

První je zapnout SO_LINGER s časovým limitem nula sekund, což vynutí TCP zásobníku odeslat paket RST a vyprázdnit stav připojení. Je tu však jedna jemnost:měli byste zavolat shutdown na deskriptoru souboru soketu před close , abyste měli možnost poslat FIN paket před RST balíček. Kód tedy bude vypadat nějak takto:

shutdown(fd, SHUT_RDWR);
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_LINGER,
           (char *) &linger, sizeof(linger));
close(fd);

Server by měl zaznamenat předčasný reset připojení pouze v případě, že FIN paket se přeuspořádá s RST paket.

Viz TCP volba SO_LINGER (nula) - když je vyžadována pro více podrobností. (Experimentálně se zdá, že nezáleží na tom, kde nastavíte setsockopt .)

Druhým je použití SO_REUSEADDR a explicitní bind (i když jste klientem), což Linuxu umožní znovu použít dočasné porty, když spustíte, než skončí čekání. Upozorňujeme, že musíte použijte bind s INADDR_ANY a port 0 , jinak SO_REUSEADDR není respektováno. Váš kód bude vypadat nějak takto:

int opts = 1;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
         (char *) &opts, sizeof(int));

struct sockaddr_in listen_addr;
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = 0;
listen_addr.sin_addr.s_addr = INADDR_ANY;
// todo: test for error
bind(fd, (struct sockaddr *) &listen_addr, sizeof(listen_addr));

// todo: test for addr
// saddr is the struct sockaddr_in you're connecting to
connect(fd, (struct sockaddr *) &saddr, sizeof(saddr));

Tato možnost je méně dobrá, protože stále zaplníte vnitřní datové struktury jádra pro připojení TCP podle netstat -an | grep -e tcp -e udp | wc -l . Dokud se tak nestane, nezačnete znovu používat porty.


To se také může stát, pokud je zadán neplatný port, například 0.


Linux
  1. Proč `md5sum` nedává stejný hash jako internet?

  2. Proč by jádro zahazovalo pakety?

  3. Ssh – Proč připojení Ssh trvá dlouho?

  1. Nelze se připojit k serveru MySQL, chyba 111

  2. Proč fclose(NULL) glibc způsobí chybu segmentace místo vracení chyby?

  3. Proč ENOENT znamená Žádný takový soubor nebo adresář?

  1. Proč získáte cp:vynechání chyby adresáře v Linuxu a jak to vyřešit

  2. Proč je riskantní poskytnout Sudo Vim přístup běžným uživatelům?

  3. Proč by si někdo vybral FreeBSD před Linuxem?