Weka kitabu "Linux API. Mwongozo wa kina"


Weka kitabu "Linux API. Mwongozo wa kina"

Habari za mchana Ninawasilisha kwa mawazo yako kitabu "Linux API. Mwongozo wa kina" (tafsiri ya kitabu Kiolesura cha Kutayarisha Linux) Inaweza kuagizwa kwenye tovuti ya mchapishaji, na ikiwa unatumia msimbo wa ofa LinuxAPI , utapokea punguzo la 30%.

Dondoo kutoka kwa kitabu kwa marejeleo:

Soketi: Usanifu wa Seva

Katika sura hii, tutajadili misingi ya kuunda seva za kurudia na zinazofanana, na pia tutaangalia daemon maalum inayoitwa inetd, ambayo inafanya iwe rahisi kuunda programu za seva za Mtandao.

Seva za kurudia na sambamba

Kuna usanifu wa kawaida wa seva ya mtandao wa soketi mbili:

  • iterative: seva hutumikia wateja mmoja baada ya mwingine, kwanza kushughulikia ombi (au maombi kadhaa) kutoka kwa mteja mmoja na kisha kwenda kwa mwingine;

  • sambamba: seva imeundwa kutumikia wateja wengi kwa wakati mmoja.

Mfano wa seva inayojirudia kulingana na foleni za FIFO tayari iliwasilishwa katika Sehemu ya 44.8.

Seva za kurudia kwa kawaida zinafaa tu katika hali ambapo maombi ya mteja yanaweza kushughulikiwa kwa haraka, kwani kila mteja analazimika kusubiri hadi wateja wengine wowote walio mbele yake wahudumiwe. Kesi ya kawaida ya utumiaji wa mbinu hii ni ubadilishanaji wa maombi moja na majibu kati ya mteja na seva.

Seva zinazofanana zinafaa katika hali ambapo kila ombi linachukua muda mwingi kulishughulikia, au ambapo mteja na seva hushiriki katika ubadilishanaji wa ujumbe mrefu. Katika sura hii, tutazingatia hasa njia ya jadi (na rahisi) ya kuunda seva zinazofanana, ambayo ni kuunda mchakato tofauti wa mtoto kwa kila mteja mpya. Utaratibu huu hufanya kazi yote ya kumtumikia mteja na kisha kumalizika. Kwa sababu kila moja ya michakato hii inafanya kazi kwa kujitegemea, inawezekana kutumikia wateja wengi kwa wakati mmoja. Kazi kuu ya mchakato wa seva kuu (mzazi) ni kuunda mtoto tofauti kwa kila mteja mpya (vinginevyo, nyuzi za utekelezaji zinaweza kuundwa badala ya taratibu).

Katika sehemu zifuatazo, tutaangalia mifano ya seva za soketi za kikoa cha mtandao zinazorudiwa na sambamba. Seva hizi mbili hutekeleza toleo lililorahisishwa la huduma ya mwangwi (RFC 862), ambayo hurejesha nakala ya ujumbe wowote uliotumwa kwake na mteja.

Mwangwi wa seva ya UDP unaorudiwa

Katika sehemu hii na inayofuata tutaanzisha seva za huduma ya echo. Inapatikana kwenye nambari ya bandari 7 na inafanya kazi kwa UDP na TCP (bandari hii imehifadhiwa, na kwa hivyo seva ya mwangwi lazima iendeshwe na haki za msimamizi).

Seva ya UDP ya mwangwi husoma kila mara datagramu na kurejesha nakala zake kwa mtumaji. Kwa kuwa seva inahitaji tu kuchakata ujumbe mmoja kwa wakati mmoja, usanifu wa kurudia utatosha. Faili ya kichwa cha seva imeonyeshwa kwenye Orodha 56.1.

Kuorodhesha 56.1. Faili ya kichwa cha programu id_echo_sv.c na id_echo_cl.c

#pamoja na "inet_sockets.h" /* Inatangaza kazi za soketi yetu */
#pamoja na "tlpi_hdr.h"

#fafanua SERVICE "echo" /* jina la huduma ya UDP */

#fafanua BUF_SIZE 500 /* Upeo wa ukubwa wa datagramu hizo
inaweza kusomwa na mteja na seva */
________________________________________________________________________ soketi/id_echo.h

Orodha ya 56.2 inaonyesha utekelezaji wa seva. Mambo yafuatayo yanafaa kuzingatiwa:

  • kuweka seva katika hali ya daemon, tunatumia kipengele cha becomeDaemon() kutoka sehemu ya 37.2;

  • ili kufanya programu iwe ngumu zaidi, tunatumia maktaba kwa kufanya kazi na soketi za kikoa cha Mtandao, zilizotengenezwa katika sehemu ya 55.12;

  • ikiwa seva haiwezi kurudisha jibu kwa mteja, huandika ujumbe kwa logi kwa kutumia syslog() simu.

Katika programu-tumizi halisi, tunaweza kuweka kikomo fulani kwa marudio ya ujumbe wa kukata miti kwa kutumia syslog(). Hii itaondoa uwezekano wa mshambulizi kufurika kumbukumbu ya mfumo. Kwa kuongeza, usisahau kwamba kila simu kwa syslog() ni ghali kabisa, kwani hutumia fsync() kwa chaguo-msingi.

Kuorodhesha 56.2. Seva ya kurudia inayotumia huduma ya mwangwi ya UDP

________________________________________________________________________________ soketi/id_echo_sv.c
#pamoja na
#pamoja na "id_echo.h"
#pamoja na "kuwa_daemon.h"

int
kuu (int argc, char *argv[])
{
int sfd;
ukubwa_t nambariSoma;
socklen_t len;
struct sockaddr_storage claddr;
char buf[BUF_SIZE];
char addrStr[IS_ADDR_STR_LEN];

ikiwa (kuwaDaemon(0) == -1)
errExit("kuwaDaemon");

sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);
ikiwa (sfd == -1) {
syslog(LOG_ERR, "Haikuweza kuunda soketi ya seva (%s)",
strerror (ya makosa));
toka(EXIT_FAILURE);

/* Pokea datagrams na urudishe nakala zake kwa watumaji */
}
kwa (;;) {
len = sizeof(muundo sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

ikiwa (idadiSoma == -1)
errExit("recvfrom");
ikiwa (tuma kwa(sfd, buf, numRead, 0, (muundo sockaddr *) &claddr, len)
!= numSoma)
syslog(LOG_WARNING, "Hitilafu katika kutoa mwangwi kwa %s (%s)",
inetAddressStr((muundo sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror (ya makosa));
}
}
________________________________________________________________________________ soketi/id_echo_sv.c

Ili kujaribu utendakazi wa seva, tunatumia programu kutoka kwa Orodha 56.3. Pia hutumia maktaba kufanya kazi na soketi za kikoa cha Mtandao, iliyoandaliwa katika sehemu ya 55.12. Kama hoja ya mstari wa amri ya kwanza, programu ya mteja inachukua jina la nodi ya mtandao ambayo seva iko. Mteja huingiza kitanzi ambapo hutuma kila hoja iliyobaki kwa seva kama datagramu tofauti, na kisha kusoma na kuchapisha datagramu anazopokea kutoka kwa seva kwa kujibu.

Kuorodhesha 56.3. Mteja wa huduma ya mwangwi ya UDP

#pamoja na "id_echo.h"

int
kuu (int argc, char *argv[])
{
int sfd, j;
size_t len;
ukubwa_t nambariSoma;
char buf[BUF_SIZE];

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

/* Unda anwani ya seva kulingana na hoja ya mstari wa amri ya kwanza */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
ikiwa (sfd == -1)
mbaya ("Haikuweza kuunganishwa na tundu la seva");

/* Tuma hoja zilizobaki kwa seva katika mfumo wa datagramu tofauti */
kwa (j = 2; j < argc; j++) {
len = strlen(argv[j]);
ikiwa (andika(sfd, argv[j], len) != len)
fatal("sehemu/iliyoshindwa kuandika");

numRead = soma(sfd, buf, BUF_SIZE);
ikiwa (idadiSoma == -1)
errExit("soma");
printf("[%ld bytes] %.*sn", (nde) numRead, (int) numRead, buf);
}
toka(EXIT_SUCCESS);
}
________________________________________________________________________________ soketi/id_echo_cl.c

Chini ni mfano wa kile tutachoona wakati wa kuendesha seva na matukio mawili ya mteja:

$su // Haki zinahitajika ili kuunganisha kwenye mlango uliohifadhiwa
password:
# ./id_echo_sv // Seva huenda katika hali ya usuli
# toka // Toa haki za msimamizi
$ ./id_echo_cl localhost hujambo ulimwengu // Mteja huyu hutuma datagramu mbili
[baiti 5] hujambo // Mteja anaonyesha jibu lililopokelewa kutoka kwa seva
[baiti 5] ulimwengu
$ ./id_echo_cl localhost kwaheri // Mteja huyu hutuma datagramu moja
[baiti 7] kwaheri

Nakutakia usomaji mzuri)

Chanzo: linux.org.ru