GNU/Linux >> Znalost Linux >  >> Linux

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

Používám send() místo write(), které nezpracovávají žádný signál:

bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
    break;
}
n2 = send(newsockfd, buffer, n, MSG_NOSIGNAL);
if (n2 == -1)
{
    close(sockfd);
    close(newsockfd);
    return;
}
if (n2 != n)
{
    break;
}

Programování soketů může být poměrně složité, protože o chybě často víte až mnohem později.

Pokud se například počítač, na který zapisujete, nenormálně vypne, volání zápisu může být úspěšné (protože jste byli schopni zapisovat do vnitřních vyrovnávacích pamětí operačního systému), ale během zavíracího volání selže.

Pokud nemáte na aplikační vrstvě způsob ověření, zda je soket aktivní (tj. odeslání zprávy a vyžadování odpovědi v určitém časovém období), nemůžete to vědět. Pokud používáte standardní protokol, může již existovat něco pro zpracování chyb.

Krátká odpověď tedy zní, že musíte zkontrolovat návratnost chyb z téměř každého volání, které se dotkne soketu (čtení, zápis, zavření atd...).


Způsob, jak zkontrolovat, zda můžete zapisovat do soketu, je překvapivě zkusit do něj zapisovat :-)

Pokud byla zásuvka uzavřena, dostanete -1 návratový kód z write a můžete prozkoumat errno abyste viděli, v čem byl problém.

Pokud je soket stále platný, ale momentálně nemůžete zapisovat žádná data, write vrátí 0. read volání se také chová podobným způsobem a vrací -1 pokud je problém.

V podstatě pro write :

  • pokud dostanete zpět -1 , došlo k problému a měli byste zkontrolovat errno zjistit, zda je obnovitelný nebo smrtelný.
  • Pokud dostanete zpět 0 , pak v tuto chvíli nemůžete nic psát (může to být nevyřízená síť nebo jiný problém, ale rozhodně ne (zatím) fatální).
  • Pokud získáte hodnotu nižší, než jste chtěli, pak nějaké dat byla odeslána. Upravte si ukazatele, abyste mohli zkusit poslat zbytek v příštím cyklu. Ne předpokládat kladnou návratovou hodnotu znamená, že byl odeslán celý blok.
  • Pokud se vám vrátí stejné číslo, jako je počet bajtů, které jste se pokusili odeslat, byla k doručení přijata celá vyrovnávací paměť.
  • Pokud dostanete zpět více, než jste požadovali, pošlete e-mail vývojářům jádra s nějakým jízlivým komentářem. To se Linusovi a spol. bude líbit :-)

Aktualizace: Jak caf upozornil v komentářích, zapomněl jsem vzít v úvahu zpracování signálu. Signál přerušeného potrubí nebo write musíte ignorovat selže interně zvýšením signálu.

Můžete to provést vložením:

struct sigaction new_actn, old_actn;
new_actn.sa_handler = SIG_IGN;
sigemptyset (&new_actn.sa_mask);
new_actn.sa_flags = 0;
sigaction (SIGPIPE, &new_actn, &old_actn);

než začnete používat funkce zásuvky. Poté můžete použít:

sigaction (SIGPIPE, &old_actn, NULL);

pro obnovení předchozího zpracování signálu.


Linux
  1. Jak zkontrolovat otevřený port na vzdáleném systému Linux

  2. Zkontrolujte limit otevřeného FD pro daný proces v Linuxu

  3. Jak napsat ovladač zařízení linux block v uživatelském prostoru?

  1. zkontrolujte všechny otevřené zásuvky v linuxovém OS

  2. Jak připojit k souboru v C pomocí Otevřít v režimu O_APPEND na linuxu?

  3. Jak určit dobu připojení soketu v systému Linux

  1. Jak zkontrolovat poslech / otevřené porty pomocí Netstat v systému Linux

  2. linuxová schránka pro čtení/zápis v C

  3. Zkontrolujte, zda je port otevřený nebo uzavřený na serveru Linux?