cs:bsd_sockets_-_zakladni_funkce

Jak jsme již uvedli, základní funkce pro vytvoření soketu a práci s ním jsou stejné pro všechny podporované rodiny protokolů. Soket IPv6/TCP se vytvoří v jazyce C obvyklým způsobem:

s = socket(PF_INET6, SOCK_STREAM);

Obdobně soket IPv6/UDP:

s = socket(PF_INET6, SOCK_DGRAM);

Také ostatní základní funkce pro práci se sokety zůstávají beze změny. Zde je jejich stručný přehled:

  • bind() - Připojení soketu k lokální adrese.
  • close() - Uzavření soketu.
  • connect() - Připojení ke vzdálenému uzlu.
  • getpeername() - Získání adresy vzdáleného uzlu, který je k soketu připojen.
  • getsockopt() - Zjištění parametrů soketu.
  • listen() - Naslouchání na soketu (čekání na žádost o spojení).
  • recv() - Čtení dat ze soketu.
  • recvfrom() - Čtení dat ze soketu. Spolu s daty se získá i adresa vzdáleného uzlu.
  • send() - Posílání dat do soketu. Soket již musí být připojen na vzdálený uzel pomocí connect().
  • sendto() - Posílání dat do soketu zároveň s udáním cílové adresy.
  • setsockopt() - Nastavení volitelných parametrů soketu.
  • shutdown() - Ukončení komunikace v jednom nebo obou směrech podle hodnoty argumentu této funkce.

Použití některých z těchto funkcí budeme prakticky demonstrovat na ukázce v závěru příspěvku.

Funkce bind() umožňuje prostřednictvím svého argumentu specifikovat zdrojovou adresu datagramů odesílaných soketem. V řadě případů nám na tom nezáleží a můžeme nechat volbu zdrojové adresy na operačním systému. V případě IPv4 bylo běžnou praxí používat funkci bind() například takto:

int s;
struct sockaddr_in zde;
zde.sin_family = AF_INET;
zde.sin_port = 0;
zde.sin_addr.s_addr = INADDR_ANY;
bzero(&(zde.sin_zero), 8);
s = socket(PF_INET, SOCK_STREAM, 0);
bind(s, (struct sockaddr *)&zde, sizeof(struct sockaddr));

Symbolická konstanta INADDR_ANY na místě adresové struktury in_addr vyjadřuje právě náš záměr ponechat volbu zdrojové IP na systému, (podobně jako nulové číslo portu o řádek výše). Vzhledem k tomu, že in_addr je de facto komplikovaně zapsaná skalární hodnota, můžeme INADDR_ANY používat i v přiřazovacích příkazech, jak jsme viděli ve výše uvedeném příkladu.

U adres IPv6 už to takto jednoduše nejde, protože typ in6_addr obsahuje šestnáctiprvkové pole. Proto je (rovněž v netinet/in.h) definována globální proměnná in6addr_any výše uvedeného typu, již lze použít stejně jako symbolickou konstantu v případě IPv4:

zde.sin6_addr.s6_addr = in6addr_any;

Druhou možností pak je použití symbolické konstanty IN6ADDR_ANY_INIT, kterou však nelze použít v přiřazovacím příkazu, nýbrž pouze při inicializaci hodnoty proměnné, například

struct in6_addr cokoli = IN6ADDR_ANY_INIT;

Zcela obdobná situace nastává v případě adresy rozhraní lokální smyčky (loopback), kterou však můžeme použít jak pro zdrojovou, tak i cílovou adresu. Pro IPv4 je k dispozici symbolická konstanta INADDR_LOOPBACK odpovídající adrese 127.0.0.1, zatímco pro IPv6 si opět můžeme vybrat jedno ze dvou řešení:

  • globální proměnná in6addr_loopback,
  • symbolická konstanta IN6ADDR_LOOPBACK_INIT použitelná pouze pro inicializaci hodnoty proměnné.
Poslední úprava:: 25.07.2019 13:11