Китоби "Linux API. Дастури ҳамаҷониба"


Китоби "Linux API. Дастури ҳамаҷониба"

Нимирӯзи ба хайр Ман ба диққати шумо китоби "Linux API. Роҳнамои ҳамаҷониба" (тарҷумаи китоб Интерфейси барномасозии Linux). Онро дар вебсайти ношир фармоиш додан мумкин аст ва агар шумо рамзи таблиғотро татбиқ кунед LinuxAPI , шумо 30% тахфиф мегиред.

Иқтибос аз китоб барои истинод:

Сокетҳо: Архитектураи сервер

Дар ин боб мо асосҳои тарҳрезии серверҳои итеративӣ ва параллелиро баррасӣ мекунем ва инчунин демони махсус бо номи inetdро дида мебароем, ки эҷоди замимаҳои сервери интернетиро осон мекунад.

Серверҳои такрорӣ ва параллелӣ

Ду меъмории сервери шабакавӣ дар асоси розетка вуҷуд дорад:

  • такроршаванда: сервер ба муштариён як-як хидмат мерасонад, аввал дархостро (ё якчанд дархостро) аз як муштарӣ коркард мекунад ва сипас ба дигараш мегузарад;

  • мувозӣ: сервер тарҳрезӣ шудааст, ки дар як вақт ба якчанд мизоҷ хидмат расонад.

Намунаи сервери итеративӣ дар асоси навбатҳои FIFO аллакай дар фасли 44.8 оварда шудааст.

Серверҳои итеративӣ одатан танҳо дар ҳолатҳое мувофиқанд, ки дархостҳои муштарӣ метавонанд ба таври кофӣ зуд коркард шаванд, зеро ҳар як муштарӣ маҷбур аст интизор шавад, ки то ба ҳама муштариёни дигар дар назди он хидмат расонида шавад. Ҳолати маъмули истифодаи ин равиш мубодилаи дархостҳо ва посухҳои ягона байни муштарӣ ва сервер мебошад.

Серверҳои параллелӣ дар ҳолатҳое мувофиқанд, ки ҳар як дархост барои коркард вақти зиёдро мегирад ё дар он ҷо мизоҷ ва сервер дар мубодилаи паёмҳои тӯлонӣ машғуланд. Дар ин боб, мо асосан ба тарзи анъанавии (ва соддатарин) тарҳрезии серверҳои параллелӣ, яъне эҷоди раванди ҷудогонаи кӯдак барои ҳар як муштарии нав тамаркуз хоҳем кард. Ин раванд тамоми корҳоро барои хидматрасонӣ ба муштарӣ иҷро мекунад ва сипас ба итмом мерасад. Азбаски ҳар яке аз ин равандҳо мустақилона амал мекунанд, мумкин аст, ки дар як вақт ба якчанд муштариён хидмат расонанд. Вазифаи асосии раванди сервери асосӣ (волид) ин эҷод кардани кӯдаки алоҳида барои ҳар як муштарии нав мебошад (алтернатива, ба ҷои равандҳо риштаҳои иҷроро эҷод кардан мумкин аст).

Дар бахшҳои минбаъда мо мисолҳои серверҳои розеткаи домени интернетии итеративӣ ва мувозиро дида мебароем. Ин ду сервер версияи соддакардашудаи хидмати echo (RFC 862) -ро амалӣ мекунанд, ки нусхаи ҳар паёме, ки муштарӣ ба он фиристодааст, бармегардонад.

Эхо-сервери такрории UDP

Дар ин ва дар боби оянда мо серверҳоро барои хидмати echo муаррифӣ хоҳем кард. Он дар бандари рақами 7 дастрас аст ва ҳам дар UDP ва ҳам TCP кор мекунад (ин порт ҳифз шудааст ва аз ин рӯ сервери echo бояд бо имтиёзҳои администратор кор кунад).

Сервери echo UDP пайваста датаграммаҳоро мехонад ва нусхаҳои онҳоро ба ирсолкунанда бармегардонад. Азбаски сервер дар як вақт танҳо як паёмро коркард мекунад, меъмории такрорӣ кифоя хоҳад буд. Файли сарлавҳа барои серверҳо дар Рӯйхати 56.1 нишон дода шудааст.

Рӯйхати 56.1. Файли сарлавҳа барои барномаҳои id_echo_sv.c ва id_echo_cl.c

#include "inet_sockets.h" /* Функсияҳои розеткаҳои моро эълон мекунад */
#include "tlpi_hdr.h"

#define SERVICE "echo" /* Номи хидмати UDP */

#define BUF_SIZE 500 /* Андозаи максималии датаграммаҳо, ки
мизоҷ ва сервер хондан мумкин аст */
_________________________________________________________________розеткаҳо/id_echo.h

Рӯйхати 56.2 татбиқи серверро нишон медиҳад. Нуқтаҳои зерин қобили таваҷҷӯҳ мебошанд:

  • барои ба реҷаи демон гузоштани сервер, мо функсияи becomeDaemon()-ро аз фасли 37.2 истифода мебарем;

  • барои зичтар кардани барнома, мо китобхонаро барои кор бо розеткаҳои домени Интернет истифода мебарем, ки дар фасли 55.12 таҳия шудааст;

  • агар сервер ба муштарӣ посухе баргардонад, он бо истифода аз занги syslog() ба гузориш паём менависад.

Дар як барномаи воқеӣ, мо эҳтимол ба басомади сабти паёмҳо бо истифода аз syslog() маҳдудият ҷорӣ мекунем. Ин имкони пур кардани сабти системаро аз ҳамлагар аз байн мебарад. Илова бар ин, фаромӯш накунед, ки ҳар як занг ба syslog() хеле гарон аст, зеро он бо нобаёнӣ fsync() -ро истифода мебарад.

Рӯйхати 56.2. Сервери итератсия, ки хидмати echo UDP-ро амалӣ мекунад

_________________________________________________________________розетҳо/id_echo_sv.c
#дарбар мегирад
#include "id_echo.h"
#include "become_daemon.h"

Int
асосӣ (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];

агар (домон шудан(0) == -1)
errExit("Daemon шудан");

sfd = inetBind (ХИЗМАТРАСОН, SOCK_DGRAM, NULL);
агар (sfd == -1) {
syslog(LOG_ERR, "Сокети сервер (%s) эҷод карда нашуд",
strerror (хато));
баромадан (EXIT_FAILURE);

/* Датаграммаҳоро қабул кунед ва нусхаҳои онҳоро ба ирсолкунандагон баргардонед */
}
барои (;;) {
len = sizeof (struct sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

агар (numRead == -1)
errExit("recvfrom");
агар (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
!= numRead)
syslog(LOG_WARNING, "Хато дар аксбардории посух ба %s (%s)",
inetAddressStr((struct sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror (хато));
}
}
_________________________________________________________________розетҳо/id_echo_sv.c

Барои санҷидани кори сервер, мо барномаро аз Listing 56.3 истифода мебарем. Он инчунин китобхонаро барои кор бо розеткаҳои доменҳои Интернет истифода мебарад, ки дар фасли 55.12 таҳия шудааст. Ҳамчун далели аввалини сатри фармон, барномаи муштарӣ номи гиреҳи шабакаро мегирад, ки сервер дар он ҷойгир аст. Мизоҷ ба ҳалқае ворид мешавад, ки дар он ҳар як аргументи боқимондаро ҳамчун датаграммаҳои алоҳида ба сервер мефиристад ва сипас датаграммаҳои дар ҷавоб аз сервер гирифтаашро мехонад ва чоп мекунад.

Рӯйхати 56.3. Мизоҷ барои хидмати echo UDP

#include "id_echo.h"

Int
асосӣ (int argc, char *argv[])
{
int sfd, j;
size_t len;
ssize_t numRead;
char buf[BUF_SIZE];

агар (argc < 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s мизбони msg…n", argv[0]);

/* Суроғаи серверро дар асоси аргументи якуми сатри фармон тартиб диҳед */
sfd = inetConnect (argv [1], ХИЗМАТРАСОН, SOCK_DGRAM);
агар (sfd == -1)
fatal("Ба васлаки сервер пайваст нашуд");

/* Аргументҳои боқимондаро ба сервер дар шакли датаграммаҳои алоҳида фиристед */
барои (j = 2; j <argc; j++) {
len = strlen(argv[j]);
агар (навиштан(sfd, argv[j], len) != len)
марговар ("қисман/навиштан ноком");

numRead = хондан (sfd, buf, BUF_SIZE);
агар (numRead == -1)
errExit("хондан");
printf("[%ld bytes] %.*sn", (long) numRead, (int) numRead, buf);
}
баромадан (EXIT_SUCCESS);
}
_________________________________________________________________розеткаҳо/id_echo_cl.c

Дар зер намунаи он чизест, ки мо ҳангоми кор кардани сервер ва ду мисоли муштарӣ мебинем:

$su // Имтиёзҳо барои пайвастшавӣ ба порти ҳифзшуда талаб карда мешаванд
Рамз:
# ./id_echo_sv // Сервер ба ҳолати замина мегузарад
# баромадан // Аз ҳуқуқҳои администратор даст кашед
$ ./id_echo_cl localhost Салом ҷаҳон // Ин муштарӣ ду датаграмма мефиристад
[5 байт] салом // Мизоҷ посухи аз сервер гирифтаашро нишон медиҳад
[5 байт] ҷаҳон
$ ./id_echo_cl localhost хайрбод // Ин муштарӣ як датаграмма мефиристад
[7 байт] хайрухуш

Ман ба шумо хониши гуворо мехоҳам)

Манбаъ: linux.org.ru