Pirtûka "Linux API. Rêbernameya Berfireh"


Pirtûka "Linux API. Rêbernameya Berfireh"

Paş nîvro Ez pirtûka “Linux API” pêşkêşî we dikim. Rêbernameyek berfireh" (wergera pirtûkê Navbera Bernameyên Linux). Ew dikare li ser malpera weşanxaneyê were ferman kirin, û heke hûn koda danasînê bicîh bikin LinuxAPI , hûn ê 30% daxistinê bistînin.

Parçeyek ji pirtûkê ji bo referansê:

Soket: Mîmariya Server

Di vê beşê de, em ê bingehên sêwirana pêşkêşkerên dubare û paralel nîqaş bikin, û her weha li daemonek taybetî ya bi navê inetd binêrin, ku çêkirina sepanên servera Înternetê hêsantir dike.

Pêşkêşkerên dubare û paralel

Du mîmariya servera torê ya bingehîn-socket-a hevpar hene:

  • dubare: pêşkêşkar yek bi yek ji xerîdaran re xizmet dike, pêşî daxwazek (an çend daxwazek) ji xerîdarek dişoxilîne û dûv re derbasî ya din dibe;

  • paralel: pêşkêşker ji bo xizmetkirina gelek xerîdar bi hevdemî hatî çêkirin.

Nimûneyek serverek dubarekirî ya ku li ser bingeha rêzikên FIFO-yê ye berê di beşa 44.8 de hate pêşkêş kirin.

Pêşkêşkerên dubare bi gelemperî tenê di rewşên ku daxwazên xerîdar dikarin bi lez û bez werin hilanîn guncan in, ji ber ku her xerîdar neçar e ku li bendê bimîne heya ku xerîdarên din ên li pêşiya wê neyên xizmet kirin. Doza karanîna gelemperî ji bo vê nêzîkbûnê pevguhertina daxwaz û bersivên yekane di navbera xerîdar û serverê de ye.

Pêşkêşkerên paralel di rewşên ku her daxwazek ji bo pêvajoyê pir girîng wext digire, an ku xerîdar û server di danûstandinên peyamên dirêj de têkildar in guncan in. Di vê beşê de, em ê bi giranî li ser awayê kevneşopî (û hêsan) sêwirana serverên paralel, ku ev e ku ji bo her xerîdarek nû pêvajoyek zarokek cihêreng biafirînin, bisekinin. Ev pêvajo hemî karan dike ku ji xerîdar re xizmet bike û dûv re bi dawî dibe. Ji ber ku her yek ji van pêvajoyan serbixwe tevdigere, gengaz e ku meriv bi hevdemî ji gelek xerîdaran re xizmet bike. Erka sereke ya pêvajoya servera sereke (dêûbav) ev e ku ji bo her xerîdarek nû zarokek veqetandî biafirîne (alternatîf, li şûna pêvajoyên xêzên darvekirinê dikare were afirandin).

Di beşên jêrîn de, em ê li mînakên pêşkêşkerên soketên domaina înternetê yên dubare û paralel binêrin. Van her du pêşkêşker guhertoyek hêsan a karûbarê echo (RFC 862) bicîh dikin, ku kopiyek her peyamek ku ji hêla xerîdar ve jê re hatî şandin vedigerîne.

Echo servera UDP ya dubare

Di vê û beşa paşîn de em ê serverên ji bo karûbarê echo bidin nasîn. Ew li ser porta jimareya 7-ê heye û hem li ser UDP û hem jî li ser TCP-ê dixebite (ev port veqetandî ye, û ji ber vê yekê servera echo divê bi mafên rêveberiyê were xebitandin).

Pêşkêşkara echo UDP bi domdarî datagraman dixwîne û kopiyên wan ji şander re vedigerîne. Ji ber ku server tenê hewce dike ku yek carî yek peyamê bişopîne, mîmariya dubare dê têrê bike. Pelê sernavê ji bo pêşkêşkeran di Lîsteya 56.1 de tê xuyang kirin.

Lîsteya 56.1. Dosya sernavê ji bo bernameyên id_echo_sv.c û id_echo_cl.c

#include "inet_sockets.h" /* Fonksiyonên soketa me diyar dike */
#include "tlpi_hdr.h"

#define SERVICE "echo" /* Navê karûbarê UDP */

#define BUF_SIZE 500 /* Mezinahiya herî zêde ya datagramên ku
dikare ji hêla xerîdar û serverê ve were xwendin */
______________________________________________________socket/id_echo.h

Lîsteya 56.2 pêkanîna serverê nîşan dide. Xalên jêrîn hêjayî balê ne:

  • ji bo ku server têxin moda daemon, em fonksiyona benDaemon() ji beşa 37.2 bikar tînin;

  • ji bo ku bernameyê tevlihevtir bikin, em pirtûkxaneyê ji bo xebata bi soketên domaina Înternetê, ku di beşa 55.12 de hatî pêşve xistin bikar tînin;

  • ger server nikaribe bersivekê ji xerîdar re vegerîne, ew bi banga syslog() re peyamek ji têketinê re dinivîse.

Di serîlêdanek rastîn de, em ê îhtîmalek sînorek li ser frekansa têketina peyaman bi karanîna syslog() ferz bikin. Ev ê îhtîmala ku êrîşkarek têketina pergalê ji holê rabike. Wekî din, ji bîr nekin ku her bangek ji syslog() re pir biha ye, ji ber ku ew bi xwerû fsync () bikar tîne.

Lîsteya 56.2. Pêşkêşkara dubarekirinê ya ku karûbarê echo UDP bicîh tîne

__________________________________________________________________socket/id_echo_sv.c
#linavxistin
#include "id_echo.h"
#include "become_daemon.h"

int
sereke (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];

heke (bibe Daemon (0) == -1)
errExit ("bibe Daemon");

sfd = inetBind(XIZMET, SOCK_DGRAM, NULL);
heke (sfd == -1) {
syslog(LOG_ERR, "Nekarî soketa pêşkêşkarê (%s) biafirîne",
strerror (errno));
derketin (EXIT_FAILURE);

/* Danegraman bistînin û kopiyên wan ji şanderan re vegerînin */
}
ji bo (;;) {
len = sizeof(avakirina sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (avakirina sockaddr *) &claddr, &len);

heke (numRead == -1)
errExit ("recvfrom");
heke (sendto(sfd, buf, numRead, 0, (sazkirina sockaddr *) & claddr, len)
!= numRead)
syslog(LOG_WARNING, "Di bersiva %s de çewtî (%s)",
inetAddressStr((sazkirina sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror (errno));
}
}
__________________________________________________________________socket/id_echo_sv.c

Ji bo ceribandina xebata serverê, em bernameya ji Lîsteya 56.3 bikar tînin. Di heman demê de ew pirtûkxaneyê ji bo xebata bi soketên domaina Înternetê, ku di beşa 55.12 de hatî pêşve xistin, bikar tîne. Wekî argumana rêza fermanê ya yekem, bernameya xerîdar navê girêka torê ya ku server lê ye digire. Xerîdar dikeve dorpêkek ku her yek ji argumanên mayî wekî datagramên cihêreng dişîne serverê, û dûv re datagramên ku ji serverê distîne di bersivê de dixwîne û çap dike.

Lîsteya 56.3. Xerîdar ji bo karûbarê echo UDP

#include "id_echo.h"

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

eger (argc < 2 || strcmp(argv[1], "--alîkarî") == 0)
usageErr("%s msg...n", argv[0]);

/* Navnîşana serverê li ser bingeha argumana rêza fermana yekem ava bikin */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
heke (sfd == -1)
fatal ("Nekarî bi soketa serverê ve were girêdan");

/* Argumanên mayî di forma datagramên cihêreng de ji serverê re bişînin */
ji bo (j = 2; j < argc; j++) {
len = strlen(argv[j]);
heke (binivîse(sfd, argv[j], len) != len)
fatal ("nivîsandina qismî/serneketî");

numRead = xwendin(sfd, buf, BUF_SIZE);
heke (numRead == -1)
errExit ("xwendin");
printf("[%ld bytes] %.*sn", (dirêj) numRead, (int) numRead, buf);
}
derketin(EXIT_SUCCESS);
}
__________________________________________________________________socket/id_echo_cl.c

Li jêr mînakek e ya ku em ê gava ku server û du mînakên xerîdar dimeşînin bibînin:

$su // Ji bo girêdana bi benderek veqetandî îmtiyaz hewce ne
Şîfre:
# ./id_echo_sv // Pêşkêşkar diçe moda paşîn
# derketin // Dev ji mafên rêveberiyê berdin
$ ./id_echo_cl localhost silav cîhan // Ev xerîdar du datagraman dişîne
[5 bytes] silav // Xerîdar bersiva ku ji serverê hatî wergirtin nîşan dide
[5 bytes] cîhan
$ ./id_echo_cl localhost bi xatirê te // Ev xerîdar yek datagramê dişîne
[7 bytes] bi xatirê te

Ez ji we re xwendinek xweş dixwazim)

Source: linux.org.ru