Section author: Vedran Miletić

Python: međuprocesna komunikacija: socketi

  • BSD sockets, poznati i kao “Berkeley sockets” i kao “Unix sockets”, su de facto standardno sučelje za međuprocesnu komunikaciju lokalno i preko računalne mreže
    • mrežne utičnice koriste klijent-poslužitelj model komunikacije
      1. Bill Joy i ekipa s UCB-a izbacuje 4.2BSD koji prvi puta uvodi mrežne utičnice
      1. preimenovani u POSIX sockets i standardizirani, razlike u imenovanju funkcija
  • podjela prema adresiranju
    • Unix domain sockets – AF_UNIX
    • Unix network sockets – AF_INET i AF_INET6
  • podjela prema pouzdanosti
    • datagramski – SOCK_DGRAM
    • tokovni – SOCK_STREAM
  • module socket (službena dokumentacija) nudi pristup BSD socket sučelju
    • koristi objekte tipa bytes u komunikaciji; kad šaljete objekte tipa str, za konverziju između tipova str i bytes koriste se str.encode() i bytes.decode()
  • socket.AF_UNIX mrežne utičnice formalno koriste datotečni sustav kao prostor adresa
    • sama komunikacija nije implementirana preko datoteka
    • procesi međusobno mogu slati podatke i opisnike datoteka
  • socket.AF_INET mrežne utičnice koriste IPv4, a socket.AF_INET6 mrežne utičnice koriste IPv6 kao prostor adresa
  • socket.SOCK_DGRAM su datagramske utičnice
    • omogućuju jednosmjernu komunikaciju kod koje klijent šalje podatke, a poslužitelj prima
    • nema mogućnosti baratanja s više klijenata, svi podaci stižu na jednu utičnicu bez obzira koji od klijenata ih šalje
    • nema osiguranja da će poslani podaci stići
  • socket.bind(address) se povezuje na adresu address (poslužiteljska strana)
  • socket.connect(address) se povezuje na adresu address (klijentska strana)
  • socket.recv(size) čita podatke s utičnice do veličine size i njih vraća
  • socket.recvfrom(size) čita podatke s utičnice do veličine size i vraća uređeni par (data, address)
  • socket.send(data) šalje podatke data na adresu na koju je utičnica povezana i vraća veličinu poslanih podataka
  • socket.sendto(data, address) šalje podatke data na adresu address i vraća veličinu poslanih podataka
  • socket.close() zatvara utičnicu; potrebno je napraviti nakon završetka rada s utičnicom, slično kao kod datoteka

Zadatak

  • Napišite komunikaciju klijenta i poslužitelja tako da klijent pošalje podatak koji korisnik unese (umjesto fiksnog niza znakova pokazanog u primjeru).
  • Dodajte zatim još jedan unos podataka i izvedite dva slanja na strani klijenta i dva primanja na strani poslužitelja.

Zadatak

Napišite klijent i poslužitelj koji koriste datagramske utičnice za komunikaciju. Korisnik na strani klijenta unosi dva broja koja se zatim odvojeno šalju poslužitelju; poslužitelj ih prima i ispisuje njihov zbroj. Pripazite kojeg tipa su podaci kojima baratate i izvedite konverziju gdje je potrebno.

Zadatak

Preradite kod tako da koristi dvije utičnice na svakoj strani i da “poslužitelj” “klijentu” šalje zbroj koji onda klijent ispisuje. (Uočite da su oba svojevrsni poslužitelj i klijent jer oba rade i bind() i connect().)

Zadatak

Napišite poslužiteljsku i klijentsku stranu aplikacije za dvosmjernu komunikaciju koristeći datagramske utičnice. Na klijentskoj strani korisnik unosi niz znakova.

  • U slučaju da niz znakova počinje znakom 0, poslužitelj kao odgovor vraća ostatak niza.
  • U slučaju da niz znakova počinje znakom 1, poslužitelj kao odgovor vraća duljinu ostatka niza.

U preostalim slučajevima niz se ne šalje. Klijentska aplikacija prekida nakon jednog slanja i primanja, a poslužiteljska nakon jednog primanja i slanja. (Uputa: koristite dvije utičnice; svaka strana radi bind() na po jednu utičnicu s koje prima podatke.)

  • socket.SOCK_STREAM su tokovne utičnice
    • omogućuju dvosmjernu komunikaciju
    • garantiraju dostavu poruka
    • postoji konekcija dvaju strana
  • poslužiteljska utičnica stvara utičnice na strani poslužitelja za klijente koji se povezuju
  • socket.listen(backlog) poslužiteljska utičnica sluša za povezivanja; čuva do backlog pokušaja
  • socket.accept() prihvaća klijenta i vraća uređeni par (socket object, address info); socket object se koristi za klijenta; kad se koristi socket.AF_UNIX address info je prazan
  • klijentska utičnica se povezuje na poslužitelj isto kao kod datagramskih

Zadatak

Preradite prethodnu aplikaciju da umjesto datagramskih koristi tokovne utičnice. Uočite da vam je sad dovoljna jedna utičnica.

Zadatak

Napišite poslužiteljsku aplikaciju koja prima više od jednog klijenta.

Iskoristite select() za provjeru postoji li novi klijent ili novi podaci za čitanje na nekoj od postojećih klijentskih utičnica.

Uočite da, obzirom da se za komunikaciju sa svakim od klijenata koristi posebna utičnica, vrlo je lako razlikovati poruke različitih klijenata.