Socket

Ez a szócikk az internetes socketeket tárgyalja. Lásd még: Unix domain socket, CPU socket, WebSocket.

A számítógép-hálózatokban a szoftvercsatorna, csatlakozó, Internet socket vagy egyszerűen socket egy Internet Protocol-alapú számítógépes hálózatban, például az interneten valamely kétirányú folyamatközi kommunikációs (IPC) hálózati folyam végpontja.

A socket kifejezést a TCP/IP protokollkészlet általában az operációs rendszer által biztosított API-jának megnevezésére is használják. Az Internet socketek lehetőséget nyújtanak a bejövő adatcsomag megfelelő alkalmazáshoz (processzhez vagy threadhez) való kézbesítésére, a helyi és távoli IP-címek és portok kombinációja alapján. Az operációs rendszer minden socketet egy kommunikáló alkalmazásprocesszhez vagy -szálhoz rendel.

A socket címe egy IP-cím (a számítógép helye) és egy portszám (ami az alkalmazáshoz köthető) együttese, hasonlóan ahhoz, ahogy a telefonkapcsolat egyik felét meghatározhatja egy telefonszám és a választott mellékállomás kombinációja.

A socket lényegében egy absztrakció, amit a Berkeley BSD Unix vezetett be. Ennek segítségével egy alkalmazói program egyszerűen hozzáférhet a TCP/IP protokollokhoz. A socket lényegében egy IP-címből, ami egy gazdagépet, és egy úgynevezett portcímből áll, ami egy alkalmazást azonosít az adott gazdagépen. Ezzel a két adattal az Interneten egyértelműen azonosíthatóak az alkalmazások.

Áttekintés

Egy internetes socketet a következők egyedi kombinációja jellemez:

  • Helyi socketcím: a helyi IP-cím és portszám
  • Távoli socketcím: távoli IP-cím és portszám; csak kiépült TCP-socketeknél. Ahogy lejjebb a kliens-szerver alfejezetben olvasható, ez azért szükséges, mert a TCP-szerver egyszerre több klienst is kiszolgálhat. A szerver egy socketet hoz létre minden kliens számára, ezek helyi socketcíme akár megegyezhet is.
  • Protokoll: A szállítási protokoll (pl. TCP, UDP), raw socket vagy más. Így tehát a TCP port 53 és az UDP port 53 különböző socketekre utal.

Az operációs rendszer, illetve a socketet létrehozó alkalmazás egyedi azonosító számmal hivatkozik a socketre, ez a socket azonosítója vagy száma. Az operációs rendszer az IP- és szállítási rétegbeli protokollfejlécekből kibányássza a socketcím-információt, majd továbbítja az IP-csomag hasznos részét a megfelelő alkalmazás számára.

Első verziója a BSD 1983-as kiadásában jelent meg.

Az IETF RFC-kben, internetes szabványokban, számos kézikönyvben, és ebben a cikkben is a socket kifejezés olyan entitásra utal, amit egyértelműen azonosít a socket száma. Más szakirodalomban[1] a socket kifejezés a socket címére utal, tehát „egy IP-cím és egy portszám kombinációjára”. A socket eredeti, az RFC 147-ben szereplő, az 1971-es ARPANET-hez kötődő definíciója szerint „a socketet egy 32 bites szám határozza meg, ahol a páros socketek a fogadó, a páratlanok a küldő socketek”. Napjainkban azonban a socket-alapú kommunikáció kétirányú.

Unix-szerű operációs rendszereken és Microsoft Windows alatt a netstat parancssori eszközzel lehet listázni az adott pillanatban élő socketeket és a kapcsolódó információkat (Unix/Linuxon a fájlrendszer alatt létező unix socketeket is listázza).

Sockettípusok

Többfajta internetes socket létezik:

  • Datagram socketek, vagy kapcsolat nélküli socketek, ezek User Datagram Protocolt (UDP) használnak.
  • Stream socketek, vagy kapcsolat-orientált socketek, ezek Transmission Control Protocolt (TCP) vagy Stream Control Transmission Protocolt (SCTP) használnak.
  • Raw socketek (vagy Raw IP socketek), jellemzően útválasztókban és más hálózati eszközökben találhatók. Itt a szállítási réteget kihagyják, és a csomagok fejlécét nem vágják le, hozzáférhető marad az alkalmazásnak. Alkalmazásszintű példák az Internet Control Message Protocol (a ping műveletről ismert ICMP), az Internet Group Management Protocol (IGMP) és az Open Shortest Path First (OSPF).[2]

Vannak nem internetes socketek is, ezek más hálózati protokollokra épülnek, pl. az Systems Network Architecture-re (SNA).[3] Lásd még a Unix domain socketeket (UDS), amiket a belső processzközi kommunikációra használnak.

A socketek állapota és a kliens-szerver modell

A szolgáltatásokat nyújtó processzek, a szerverek induláskor, „figyel”, „hallgatózó” vagy „hallgató” (listening) állapotban lévő socketeket hoznak létre. Ezek a socketek arra várakoznak, hogy egy kliens megszólítsa őket. Egy hallgatózó TCP socket esetén a netstat által kijelzett távoli cím 0.0.0.0 és a távoli port 0 lehet. Egy TCP szerver jellemzően úgy szolgál ki egyszerre több klienst, hogy minden klienshez létrehoz egy gyerekprocesszt, és a TCP-kapcsolatok a gyerekprocessz és a kliens között épülnek ki. Egyedi, „dedikált socketek” jönnek létre minden ilyen kapcsolathoz. Ezek akkor tekinthetők „élő” (established) állapotúnak, amikor a távoli sockettel kiépül a socket-socket közötti virtuális áramkör (virtual connection/virtual circuit, VC), más néven TCP session vagy munkamenet, ami egy duplex bytestream átvitelét biztosítja.

A netstat parancs által kijelzett további TCP socketállapotok közé tartoznak: Syn-sent, Syn-Recv, Fin-wait1, Fin-wait2, Time-wait, Close-wait és Closed, amik a kapcsolat kiépülésének és lezárásának különböző lépéseire utalnak (a magyar változatokat lásd a netstat cikkben).[4]

A szerver tehát létrehozhat egyidejűleg több, ugyanazzal a helyi portszámmal és IP-címmel rendelkező TCP socketet, melyek mindegyikéhez tartozik egy saját gyermek-szerverprocessz, ami a saját kliensprocesszét szolgálja ki. Ezeket az operációs rendszer különböző socketeknek tekinti, mivel a távoli socket címe különbözik; tehát különböznek a socket-párban (rendezett szám-n-es vagy tuple), lásd lejjebb.

Egy UDP socket állapota sosem lehet „élő” (established), mivel az UDP kapcsolat nélküli. Így a netstat nem mutatja az UDP socketek állapotát. Egy UDP szerver nem is hoz létre az egyidejűleg kiszolgált kliensek számára külön gyerekprocesszeket, ehelyett ugyanaz a processz kezeli az összes távoli klienstől érkező adatcsomagokat, beérkezésük sorrendjében. Ez azt is jelenti, hogy az UDP socketeket nem azonosítja egyértelműen a távoli címük, csak a helyi cím, bár természetesen minden üzenethez tartozik egy megfelelő távoli socketcím.

Socketpárok

Az egymással kommunikáló helyi és távoli socketet együtt socketpár névvel illetik. Minden socketpár leírható egy egyedi rendezett 4-esként, ami a forrás és cél-IP-címekből és portcímekből áll, azaz a helyi és a távoli socketcímekből.[5][6] A föntebb leírtak szerint a TCP esetében minden egyedi socketpár-négyeséhez tartozik egy socketszám, míg az UDP-nél minden egyedi helyi socketcímhez tartozik egy socketszám.

Implementációs kérdések

A TCP Socket folyamatábrája

A socketeket általában egy API programkönyvtár segítségével valósítják meg, ahogy már az 1983-as Berkeley sockets esetében is történt. A legtöbb implementáció a Berkeley socketeken alapul, ahogy például az 1991-es Winsock is. Más API-megvalósítások is léteznek, mint a STREAMS-alapú Transport Layer Interface (TLI).

Az API-t használó alkalmazások fejlesztését socket-programozásnak vagy hálózati programozásnak is nevezik.

Néhány példa az API által nyújtott jellemző függvényekre vagy eljárásokra:[7]

  • A socket() létrehoz egy új, adott sockettípusnak megfelelő, egész számmal azonosított socketet, és rendszererőforrásokat rendel hozzá.
  • A bind() jellemzően szerveroldalon használatos, egy socketet hozzárendel egy socket-címstruktúrához, azaz egy adott helyi portszámhoz és IP-címhez.
  • A listen() szerveroldalon használatos, egy kapcsolt TCP socketet hallgatózó állapotba állít.
  • A connect() kliensoldalon használatos, szabad helyi portszámot rendel egy sockethez. TCP socket esetén megkísérel új TCP kapcsolatot létrehozni.
  • Az accept() szerveroldalon használatos. Elfogad egy a távoli klienstől érkezett, új TCP-kapcsolat létesítésére irányuló próbálkozást, és létrehoz egy új socketet, amihez az iménti TCP-kapcsolat címpárosát rendeli hozzá.
  • A send() és recv(), avagy write() és read(), esetleg recvfrom() és sendto() a távoli sockettel való kommunikációra (küldés/fogadásra) szolgálnak.
  • A close() hatására a rendszer felszabadítja a sockethez rendelt erőforrásokat. TCP esetén a kapcsolat megszakad.
  • A gethostbyname() és gethostbyaddr() feloldja a hostneveket és -címeket.
  • A select() socketek egy listájából visszaadja azokat, amelyekből olvasni lehet, amelyekbe írni lehet, vagy amelyekkel probléma adódott.
  • A poll() egy socket állapotának vizsgálatára szolgál. Tesztelni lehet, hogy a socket írható, olvasható, vagy probléma adódott vele.

Socketek hálózati eszközökben

A socket koncepciója alapvetően az internetprotokoll szállítási rétegében jelenik meg. A hálózati eszközök, pl. útválasztók és hálózati kapcsolók nem kell, hogy implementálják a szállítási réteget, mivel a switchek az adatkapcsolati rétegben, a routerek a hálózati rétegben működnek. Az állapottartó tűzfalak, hálózati címfordítók és proxyk azonban számon tartják az aktív socketpárokat. A fair queuing, a layer 3 switching és a routerek quality of service (QoS) megoldásainál a csomagok áramlása (packet flow) meghatározható a socketpárok információinak kinyerésével.

A hálózati eszközökön általában elérhetők a raw socketek, és útválasztási protokollokban (pl. IGMP, OSPF), illetve az Internet Control Message Protocolban (ICMP) van szükség rá.

Korai megvalósítások

Az 1983-as Berkeley sockets (úgy is, mint a BSD socket API) az 1983-ban megjelent 4.2BSD Unix operációs rendszer API-jaként jelent meg először. De csak 1989-ben tudott a Kaliforniai Egyetem (UC Berkeley) az AT&T licenckorlátozásaitól mentes operációs rendszert és hálózati könyvtárat kiadni.[8]

Az 1987-es Transport Layer Interface (TLI) az AT&T UNIX System V Release 3 (SVR3) hálózati API-ja volt,[9] ami a Release 4-be (SVR4) is utat talált.[10][11]

Szintén a korai implementációk közé tartoznak a TOPS-20-ra,[12] az MVS-re,[12] a VM-re[12] és az IBM-DOS-ra (PCIP)[12][13] kihozott megvalósítások.

Jegyzetek

  1. Cisco Networking Academy Program, CCNA 1 and 2 Companion Guide Revised Third Edition, P.480, ISBN 1-58713-150-1
  2. Raw IP Networking FAQ. [2012. január 19-i dátummal az eredetiből archiválva]. (Hozzáférés: 2012. január 1.)
  3. www-306.ibm.com - AnyNet Guide to Sockets over SNA. [2008. május 3-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 16.)
  4. colorado.edu - Linux - netstat(8)
  5. books.google.com - UNIX Network Programming: The sockets networking API
  6. books.google.com - Designing BSD Rootkits: An Introduction to Kernel Hacking
  7. Stevens, Richard. UNIX Network Programming, Volume 1, Second Edition: Networking APIs: Sockets. ISBN 0-13-490012-X 
  8. Wikipedia: Berkeley sockets 2011-02-18
  9. (Goodheart 1994, p. 11)
  10. (Goodheart 1994, p. 17)
  11. Wikipedia: Transport Layer Interface 2011-02-18
  12. a b c d historyofcomputercommunications.info - Book: 9.8 TCP/IP and XNS 1981 - 1983. [2018. június 17-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 16.)
  13. mit.edu - The Desktop Computer as a Network Participant.pdf 1985

Fordítás

  • Ez a szócikk részben vagy egészben az Internet socket című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.

További információk

  • Client/Server Programming with TCP/IP Sockets
  • Beej's Guide to Network Programming
  • Highly commented C++ Win32 Socket Server Class
  • Java TCP/IP Sockets server and client
  • Informatika Informatikai portál • összefoglaló, színes tartalomajánló lap