Ktieb “Linux API. Gwida Komprensiva"


Ktieb “Linux API. Gwida Komprensiva"

Il-waranofsinhar it-tajjeb Nippreżenta għall-attenzjoni tiegħek il-ktieb “Linux API. Gwida komprensiva” (traduzzjoni tal-ktieb L-Interface tal-Programmazzjoni tal-Linux). Jista 'jiġi ordnat fuq il-websajt tal-pubblikatur, u jekk tapplika l-kodiċi promozzjonali LinuxAPI , inti tirċievi skont ta '30%.

Silta mill-ktieb għal referenza:

Sokits: Arkitettura tas-Server

F'dan il-kapitolu, se niddiskutu l-baŜi tat-tfassil ta 'servers iterattivi u paralleli, u nħarsu wkoll lejn daemon speċjali msejjaħ inetd, li jagħmilha aktar faċli biex jinħolqu applikazzjonijiet ta' server tal-Internet.

Servers iterattivi u paralleli

Hemm żewġ arkitetturi komuni tas-server tan-netwerk ibbażati fuq socket:

  • iterattiv: is-server iservi lill-klijenti wieħed kull darba, l-ewwel jipproċessa talba (jew diversi talbiet) minn klijent wieħed u mbagħad jimxi għall-ieħor;

  • parallel: is-server huwa ddisinjat biex iservi klijenti multipli simultanjament.

Eżempju ta' server iterattiv ibbażat fuq kjuwijiet FIFO kien diġà ppreżentat fit-Taqsima 44.8.

Is-servers iterattivi huma normalment adattati biss f'sitwazzjonijiet fejn it-talbiet tal-klijenti jistgħu jiġu pproċessati pjuttost malajr, peress li kull klijent huwa mġiegħel jistenna sakemm xi klijenti oħra quddiemu jkunu ġew innotifikati. Każ ta' użu komuni għal dan l-approċċ huwa l-iskambju ta' talbiet u tweġibiet uniċi bejn klijent u server.

Servers paralleli huma adattati f'każijiet fejn kull talba tieħu ammont sinifikanti ta 'żmien biex tipproċessa, jew fejn il-klijent u s-server jidħlu fi skambji ta' messaġġi twal. F'dan il-kapitolu, se niffukaw prinċipalment fuq il-mod tradizzjonali (u l-aktar sempliċi) ta 'tfassil ta' servers paralleli, li huwa li jinħoloq proċess tifel separat għal kull klijent ġdid. Dan il-proċess iwettaq ix-xogħol kollu biex iservi lill-klijent u mbagħad jispiċċa. Minħabba li kull wieħed minn dawn il-proċessi jopera b'mod indipendenti, huwa possibbli li jinqdew klijenti multipli simultanjament. Il-kompitu ewlieni tal-proċess tas-server prinċipali (ġenitur) huwa li jinħoloq tifel separat għal kull klijent ġdid (alternattivament, jistgħu jinħolqu ħjut ta 'eżekuzzjoni minflok proċessi).

Fis-sezzjonijiet li ġejjin, se nħarsu lejn eżempji ta 'servers ta' socket ta 'dominju tal-internet iterattivi u paralleli. Dawn iż-żewġ servers jimplimentaw verżjoni simplifikata tas-servizz echo (RFC 862), li jirritorna kopja ta 'kull messaġġ mibgħut lilha minn klijent.

Eku iterattiv tas-server UDP

F'din it-taqsima u fit-taqsima li jmiss se nintroduċu s-servers għas-servizz echo. Huwa disponibbli fuq il-port numru 7 u jaħdem kemm fuq UDP kif ukoll fuq TCP (dan il-port huwa riżervat, u għalhekk is-server tal-echo għandu jitħaddem bi privileġġi ta 'amministratur).

Is-server Echo UDP kontinwament jaqra datagrams u jirritorna kopji tagħhom lill-mittent. Peress li s-server jeħtieġ biss jipproċessa messaġġ wieħed kull darba, arkitettura iterattiva tkun biżżejjed. Il-fajl header għas-servers huwa muri fil-Elenku 56.1.

Elenku 56.1. Fajl header għall-programmi id_echo_sv.c u id_echo_cl.c

#include "inet_sockets.h" /* Jiddikjara l-funzjonijiet tas-socket tagħna */
#include "tlpi_hdr.h"

#define SERVICE "echo" /* Isem tas-servizz UDP */

#define BUF_SIZE 500 /* Daqs massimu ta 'datagrams li
jista' jinqara mill-klijent u mis-server */
___________________________________________________________________________sockets/id_echo.h

Lista 56.2 turi l-implimentazzjoni tas-server. Ta’ min jinnota l-punti li ġejjin:

  • biex tpoġġi s-server fil-modalità daemon, nużaw il-funzjoni becomeDaemon() mit-taqsima 37.2;

  • biex nagħmlu l-programm aktar kompatt, nużaw il-librerija biex naħdmu ma 'sockets tad-dominju tal-Internet, żviluppati fit-taqsima 55.12;

  • jekk is-server ma jistax jirritorna tweġiba lill-klijent, jikteb messaġġ fil-log billi juża s-sejħa syslog().

F'applikazzjoni reali, x'aktarx nimponnu xi limitu fuq il-frekwenza tal-illoggjar ta' messaġġi bl-użu ta' syslog(). Dan jelimina l-possibbiltà li attakkant ifur il-log tas-sistema. Barra minn hekk, tinsiex li kull sejħa għal syslog() hija pjuttost għalja, peress li tuża fsync() awtomatikament.

Elenku 56.2. Server ta' iterazzjoni li jimplimenta s-servizz ta' eku UDP

_________________________________________________________________sockets/id_echo_sv.c
#include
#include "id_echo.h"
#include "become_daemon.h"

int
main(int argc, char *argv[])
{
int sfd;
ssize_t numRead;
socklen_t len;
struct sockaddr_storage claddr;
char buf[BUF_SIZE];
char addrStr[IS_ADDR_STR_LEN];

jekk (isirDaemon(0) == -1)
errExit("becomeDaemon");

sfd = inetBind (SERVIZZ, SOCK_DGRAM, NULL);
jekk (sfd == -1) {
syslog(LOG_ERR, "Ma setgħetx toħloq socket tas-server (%s)",
strerror(errno));
ħruġ(ĦRUĠ_FAILURE);

/* Irċievi datagrammi u rritorna kopji tagħhom lill-mittenti */
}
għal (;;) {
len = sizeof(struct sockaddr_storage);
numRead = recvfrom (sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

jekk (numRead == -1)
errExit("recvfrom");
jekk (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
!= numRead)
syslog(LOG_WARNING, "Żball li jirrepeti rispons għal %s (%s)",
inetAddressStr((struct sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror(errno));
}
}
_________________________________________________________________sockets/id_echo_sv.c

Biex tittestja l-operat tas-server, nużaw il-programm minn Lista 56.3. Juża wkoll il-librerija biex taħdem mas-sockets tad-dominju tal-Internet, żviluppata fit-taqsima 55.12. Bħala l-ewwel argument tal-linja tal-kmand, il-programm klijent jieħu l-isem tan-node tan-netwerk li fuqu jinsab is-server. Il-klijent jidħol f'linja fejn jibgħat kull wieħed mill-argumenti li jifdal lis-server bħala datagrammi separati, u mbagħad jaqra u jistampa d-datagrammi li jirċievi mis-server bħala tweġiba.

Elenku 56.3. Klijent għal servizz ta' eku UDP

#include "id_echo.h"

int
main(int argc, char *argv[])
{
int sfd, j;
size_t len;
ssize_t numRead;
char buf[BUF_SIZE];

jekk (argc < 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s msg tal-host...n", argv[0]);

/* Ifforma l-indirizz tas-server ibbażat fuq l-ewwel argument tal-linja tal-kmand */
sfd = inetConnect(argv[1], SERVIZZ, SOCK_DGRAM);
jekk (sfd == -1)
fatal ("Ma setgħetx tikkonnettja mas-socket tas-server");

/* Ibgħat l-argumenti li jifdal lis-server fil-forma ta' datagrammi separati */
għal (j = 2; j < argc; j++) {
len = strlen(argv[j]);
jekk (ikteb(sfd, argv[j], len) != len)
fatali ("kitba parzjali/falluta");

numRead = aqra (sfd, buf, BUF_SIZE);
jekk (numRead == -1)
errExit ("aqra");
printf("[%ld bytes] %.*sn", (twil) numRead, (int) numRead, buf);
}
ħruġ(ĦRUĠ_SUĊĊESS);
}
_________________________________________________________________sockets/id_echo_cl.c

Hawn taħt hawn eżempju ta 'dak li se naraw meta nħaddmu s-server u żewġ istanzi tal-klijenti:

$su // Privileġġi huma meħtieġa biex jorbtu ma' port riservat
password:
# ./id_echo_sv // Is-server jidħol fil-modalità tal-isfond
# ħruġ // Iċedi d-drittijiet tal-amministratur
$ ./id_echo_cl localhost hello world // Dan il-klijent jibgħat żewġ datagrammi
[5 bytes] hello // Il-klijent juri r-risposta li waslet mis-server
[5 bytes] dinja
$ ./id_echo_cl localhost addiju // Dan il-klijent jibgħat datagramma waħda
[7 bytes] addiju

Nixtieqilkom qari pjaċevoli)

Sors: linux.org.ru