Práca so vstupom a výstupom:

  • Synchrónna
  • Asynchrónna

Synchrónna práca so vstupom:

  • Vyšlem požiadavku
  • Čakám na splnenie
  • Spracujem výsledok

Výhody:

Jednoduchosť

Nevýhody:

Čakanie sa môže natiahnuť do nekonečna (deadlock)

Asynchrónna práca so vstupom:

  • Vyšlem požiadavku
  • Pozriem či bola splnená okamžite
  • Ak bola splnená, spracujem ju.
  • Ak nebola splnená, pokračujem v program.

Výhody:

  • Môžem robit viac vecí naraz
  • Väčšia efektivita - menej času strávim čakaním.

Nevýhody:

  • Väčšia zložitosť

Aplikácie asynchrónneho programovania:

  • Webové aplikácie
  • Databázy a objektové úložiská
  • Distribuované aplikácie
  • Hry

Asynchrónne programovanie v C

Na nízkej úrovni:

  • select (Windows and Linux)
  • poll API (Linux)

Na vyššej úrovni:

  • Libuv, libevent, libev

Asynchrónne programovanie v iných programovacích jazykoch

  • Node.js (Javascript)
  • Asyncio (Python)

Programovanie soketu v C

Server         Client

socket()         socket()
bind()           connect()
listen()
accept()
read()   <----   write()
write()  ---->   read()
close()          close()

Socket je dostupný pomocou svojho čísla

O sokety sa stará operačný systém

Otvorenie soketu

int sockfd = socket(domain, type, protocol);

sockfd - číslo soketu, podobné ako smerník na súbor.

Nastavenie vlastností pre socket.

int setsockopt(int sockfd, int level, int optname,  const void *optval, socklen_t optlen);

Čakanie na nové spojenie na strane servra

Väzba na konkrétne rozhranie, vyhradenie pre počúvajúci server:

    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

Počúvanie na porte:

    int listen(int sockfd, int backlog);

Vytvorenie nového spojenia

int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

Čítanie a zápis do socketu

Je podobné ako do súboru

read()
write()

Viacero spojení naraz select()

#include <manifest.h>
#include <socket.h>
#include <bsdtypes.h>
#include <bsdtime.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)

Viacero spojení naraz

  • asynnchrónne programovanie.
  • viac procesov pomocou fork()
  • viac vlákien pomocou pthread

Asynchrónna slučka (Event Loop)

  +-------------------------+
  |  Inicializácia socketov |
  +----------+--------------+
             v
  +----------+--------------+
  |   select() / poll()     |<-------+
  +----------+--------------+        |
     +-------+-------+               |
     v               v               |
+----------+   +--------+            |
| spojenie |   | dáta   |            |
+----+-----+   +----+---+            |
     v               v               |
+----------+   +----------+          |
| accept() |   | read() / |          |
| pridaj fd|   | write()  |          |
+----+-----+   +----+-----+          |
     +-------+-------+---------------+

Asynchrónna slučka – príklad v C

    while (1) {
        for (int i = 0; i < nclients; i++) {
            FD_SET(client_fds[i], &read_fds);
            if (client_fds[i] > max_fd) max_fd = client_fds[i];
        }
        // Čakaj na aktivitu (blokuje až do udalosti)
        select(max_fd + 1, &read_fds, NULL, NULL, NULL);
        // Nové spojenie?
        if (FD_ISSET(server_fd, &read_fds)) {
            int new_fd = accept(server_fd, NULL, NULL);
            client_fds[nclients++] = new_fd;
        }
        // Dáta od klientov?
        for (int i = 0; i < nclients; i++) {
            if (FD_ISSET(client_fds[i], &read_fds)) {
                int n = read(client_fds[i], buf, sizeof(buf));
                if (n <= 0) {
                    close(client_fds[i]);
                    client_fds[i] = client_fds[--nclients]; // odober
                } else 
                    write(client_fds[i], buf, n); // echo
            }
        }
    }

Zdroje

  • https://www.geeksforgeeks.org/socket-programming-cc/
  • https://www.ibm.com/docs/en/zos/2.4.0?topic=calls-select
  • http://codingbison.com/c/c-sockets-select.html
  • https://www.ibm.com/docs/en/i/7.1?topic=designs-using-poll-instead-select
  • https://www.csd.uoc.gr/~hy556/material/tutorials/cs556-3rd-tutorial.pdf
Reload?