Bókin „Linux API. Alhliða leiðarvísir»


Bókin „Linux API. Alhliða leiðarvísir»

Góðan daginn Ég vek athygli þína á bókinni „Linux API. Alhliða handbók "(þýðing bókarinnar Linux forritunarviðmótið). Það er hægt að panta á vefsíðu útgefanda, og ef þú notar kynningarkóðann LinuxAPI þú færð 30% afslátt.

Útdráttur úr bókinni til upprifjunar:

Innstungur: miðlaraarkitektúr

Í þessum kafla munum við fjalla um grunnatriði hönnunar ítrekaðra og samhliða netþjóna, sem og sérstakan inetd púka sem auðveldar gerð netforrita á netþjóni.

Endurtekning og samhliða netþjónar

Það eru tveir algengir fals-undirstaða netþjónaarkitektúra:

  • endurtekið: þjónninn þjónar viðskiptavinum einum í einu, vinnur fyrst úr beiðni (eða nokkrum beiðnum) eins viðskiptavinar og heldur síðan áfram á næsta;

  • samhliða: þjónninn er hannaður til að þjóna mörgum viðskiptavinum á sama tíma.

Kafli 44.8 hefur þegar gefið dæmi um endurtekningarþjón sem byggir á FIFO biðröðum.

Endurtekningarþjónar henta venjulega aðeins í aðstæðum þar sem hægt er að vinna úr beiðni viðskiptavina nokkuð fljótt, þar sem hver viðskiptavinur þarf að bíða þar til aðrir viðskiptavinir fyrir framan hann hafa verið afgreiddir. Algengt notkunartilvik fyrir þessa nálgun er að skiptast á stakum beiðnum og svörum milli viðskiptavinar og netþjóns.

Samhliða netþjónar henta vel í þeim tilfellum þar sem hver beiðni tekur umtalsverðan tíma að vinna úr, eða biðlari og þjónn hafa langa skilaboðaskipti. Í þessum kafla munum við aðallega einbeita okkur að hefðbundnu (og auðveldasta) leiðinni til að hanna samhliða netþjóna, sem er að búa til sérstakt undirferli fyrir hvern nýjan viðskiptavin. Slíkt ferli vinnur alla vinnu við að þjónusta viðskiptavininn, að því loknu lýkur því. Þar sem hvert þessara ferla starfar sjálfstætt er hægt að þjóna mörgum viðskiptavinum á sama tíma. Aðalverkefni aðalþjónsferlisins (foreldri) er að búa til sérstakt barn fyrir hvern nýjan viðskiptavin (að öðrum kosti, í stað ferla, geturðu búið til framkvæmdarþræði).

Í eftirfarandi köflum munum við skoða dæmi um endurtekna og samhliða netþjóna byggða á innstungum fyrir netlén. Þessir tveir netþjónar innleiða einfaldaða útgáfu af bergmálsþjónustunni (RFC 862) sem skilar afriti af öllum skilaboðum sem viðskiptavinurinn sendir henni.

echo iteration udp þjónn

Í þessum og næsta kafla munum við kynna netþjóna fyrir echo þjónustuna. Það er fáanlegt á gátt númer 7 og virkar bæði yfir UDP og TCP (þessi höfn er frátekin og því þarf að keyra echo serverinn með administrator réttindi).

Echo UDP þjónninn les stöðugt gagnarit og skilar afriti af þeim til sendanda. Þar sem þjónninn þarf aðeins að vinna úr einu skeyti í einu, mun endurtekinn arkitektúr duga hér. Hausskrá fyrir netþjóna er sýnd í skráningu 56.1-XNUMX.

Skráning 56.1. Hausskrá fyrir forrit id_echo_sv.c og id_echo_cl.c

#include "inet_sockets.h" /* Lýsir falsaðgerðum okkar */
#include "tlpi_hdr.h"

#define SERVICE "echo" /* UDP þjónustuheiti */

#define BUF_SIZE 500 /* Hámarksstærð gagnagramma sem
hægt að lesa af biðlara og þjóni */
________________________________________________________________________ sockets/id_echo.h

Skráning 56.2-XNUMX sýnir útfærslu netþjónsins. Vert er að hafa í huga eftirfarandi atriði:

  • til að setja þjóninn í púkaham notum við aðgerðina becomeDaemon() úr kafla 37.2;

  • til að gera forritið þéttara notum við innstungusafnið fyrir netlén sem þróað var í kafla 55.12;

  • ef þjónninn getur ekki skilað svari til biðlarans, skrifar hann skilaboð í notendaskrána með því að nota syslog() kallið.

Í alvöru forriti myndum við líklega setja ákveðin takmörk á tíðni skráningarskilaboða með syslog(). Þetta myndi útiloka möguleikann á að árásarmaður flæði yfir kerfisskránni. Hafðu líka í huga að hvert syslog() símtal er frekar dýrt, þar sem það notar fsync() sjálfgefið.

Skráning 56.2. Endurtekningarþjónn sem útfærir echo UDP þjónustuna

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

int
main(int argc, char *argv[])
{
int sfd;
ssize_t numRead;
socklen_tlen;
struct sockaddr_geymsla claddr;
charbuf[BUF_SIZE];
bleikju addrStr[IS_ADDR_STR_LEN];

if (verður Daemon(0) == -1)
errExit("becomeDaemon");

sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);
if (sfd == -1) {
syslog(LOG_ERR, "Gat ekki búið til netþjónstengi (%s)",
strerror (villa));
hætta (EXIT_FAILURE);

/* Fáðu gagnaskrár og skilaðu afritum til sendenda */
}
fyrir(;;) {
len = sizeof(struct sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

ef (talaLestur == -1)
errExit("recvfrom");
if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
!=númer Lesið)
syslog(LOG_WARNING, "Villa við að bergmála svar við %s (%s)",
inetAddressStr((struct sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror (villa));
}
}
_________________________________________________________________sockets/id_echo_sv.c

Við notum forritið í skráningu 56.3 til að prófa netþjóninn. Það notar einnig Internet lénsinnstungusafnið sem þróað var í kafla 55.12. Biðlaraforritið tekur nafn nethýsilsins þar sem þjónninn er staðsettur sem fyrstu rökin á skipanalínunni. Viðskiptavinurinn fer inn í lykkju þar sem hann sendir hvert af eftirstöðvunum til þjónsins sem aðskilin gagnagröf og les síðan og gefur út gagnagröfin sem berast frá þjóninum sem svar.

Skráning 56.3. Viðskiptavinur fyrir echo UDP þjónustu

#include "id_echo.h"

int
main(int argc, char *argv[])
{
int sfd,j;
stærð_tlen;
ssize_t numRead;
charbuf[BUF_SIZE];

if (argc < 2 || strcmp(argv[1], "--hjálp") == 0)
usageErr("%s gestgjafi msg...n", argv[0]);

/* Myndaðu netfangið miðlara byggt á fyrstu skipanalínunni */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
ef (sfd == -1)
fatal("Gat ekki tengst við netþjóninnstunguna");

/* Sendu restina af rökunum til þjónsins sem aðskilin gagnagröf */
fyrir (j = 2; j < argc; j++) {
len = strlen(argv[j]);
ef (skrifaðu(sfd, argv[j], len) != len)
fatal("að hluta/mistókst skrifa");

numRead = read(sfd, buf, BUF_SIZE);
ef (talaLestur == -1)
errExit("lesa");
printf("[%ld bæti] %.*sn", (langur) numRead, (int) numRead, buf);
}
hætta (EXIT_SUCCESS);
}
_________________________________________________________________innstungur/id_echo_cl.c

Eftirfarandi er dæmi um það sem við munum sjá þegar við ræsum þjóninn og tvö tilvik biðlara:

$ su // Krefst réttinda til að bindast við frátekna höfn
Lykilorð:
# ./id_echo_sv // Miðlarinn fer í bakgrunninn
# exit // Afsala stjórnunarréttindum
$ ./id_echo_cl localhost halló heimur // Þessi viðskiptavinur sendir tvö gagnagröf
[5 bæti] halló // Biðlarinn gefur út svarið sem berast frá þjóninum
[5 bæti] heimur
$ ./id_echo_cl localhost bless // Þessi viðskiptavinur sendir eitt gagnagramm
[7 bæti] bless

Ég óska ​​þér ánægjulegrar lestrar)

Heimild: linux.org.ru