Práca so vstupom a výstupom:
Synchrónna práca so vstupom:
Výhody:
Jednoduchosť
Nevýhody:
Čakanie sa môže natiahnuť do nekonečna (deadlock)
Asynchrónna práca so vstupom:
Výhody:
Nevýhody:
Aplikácie asynchrónneho programovania:
Asynchrónne programovanie v C
Na nízkej úrovni:
Na vyššej úrovni:
Asynchrónne programovanie v iných programovacích jazykoch
Server Client
socket() socket()
bind() connect()
listen()
accept()
read() <---- write()
write() ----> read()
close() close()
O sokety sa stará operačný systém
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);
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);
int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Je podobné ako do súboru
read()
write()
#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)
fork()pthread +-------------------------+
| Inicializácia socketov |
+----------+--------------+
v
+----------+--------------+
| select() / poll() |<-------+
+----------+--------------+ |
+-------+-------+ |
v v |
+----------+ +--------+ |
| spojenie | | dáta | |
+----+-----+ +----+---+ |
v v |
+----------+ +----------+ |
| accept() | | read() / | |
| pridaj fd| | write() | |
+----+-----+ +----+-----+ |
+-------+-------+---------------+
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
}
}
}