Linux API kitobi. To'liq qo'llanma»


Linux API kitobi. To'liq qo'llanma»

Hayrli kun! Men sizning e'tiboringizga "Linux API. To'liq qo'llanma "(kitob tarjimasi Linux dasturlash interfeysi). Uni nashriyotning veb-saytida buyurtma qilish mumkin va agar siz promo-kodni qo'llasangiz LinuxAPI 30% chegirma olasiz.

Ko'rib chiqish uchun kitobdan parcha:

Soketlar: server arxitekturasi

Ushbu bobda biz iterativ va parallel serverlarni loyihalash asoslarini, shuningdek, server tomonidagi Internet ilovalarini yaratishni osonlashtiradigan maxsus inetd demonini muhokama qilamiz.

Iteratsiya va parallel serverlar

Soketga asoslangan ikkita umumiy tarmoq serveri arxitekturasi mavjud:

  • iterativ: server mijozlarga birma-bir xizmat ko'rsatadi, avval bitta mijozning so'rovini (yoki bir nechta so'rovlarini) qayta ishlaydi va keyin ikkinchisiga o'tadi;

  • parallel: server bir vaqtning o'zida bir nechta mijozlarga xizmat ko'rsatish uchun mo'ljallangan.

44.8-bo'lim allaqachon FIFO navbatlariga asoslangan iteratsiya serverining namunasini taqdim etgan.

Iteratsiya serverlari odatda faqat mijoz so'rovlari juda tez ko'rib chiqilishi mumkin bo'lgan holatlarda mos keladi, chunki har bir mijoz o'z oldidagi boshqa mijozlarga xizmat ko'rsatilguncha kutishi kerak. Ushbu yondashuv uchun umumiy foydalanish holati mijoz va server o'rtasida yagona so'rovlar va javoblarni almashishdir.

Parallel serverlar har bir so'rovni qayta ishlash uchun ko'p vaqt talab qiladigan yoki mijoz va server uzoq vaqt davomida xabar almashinuviga ega bo'lgan hollarda mos keladi. Ushbu bobda biz asosan parallel serverlarni loyihalashning an'anaviy (va eng oson) usuliga, ya'ni har bir yangi mijoz uchun alohida bola jarayonini yaratishga e'tibor qaratamiz. Bunday jarayon mijozga xizmat ko'rsatishning barcha ishlarini bajaradi, shundan so'ng u tugaydi. Ushbu jarayonlarning har biri mustaqil ravishda ishlaganligi sababli, bir vaqtning o'zida bir nechta mijozlarga xizmat ko'rsatish mumkin. Asosiy server jarayonining (ota-ona) asosiy vazifasi - har bir yangi mijoz uchun alohida bola yaratish (variant sifatida siz jarayonlar o'rniga ijro tishlarini yaratishingiz mumkin).

Keyingi bo'limlarda biz internet domen soketlariga asoslangan iterativ va parallel serverlar misollarini ko'rib chiqamiz. Ushbu ikkita server echo xizmatining soddalashtirilgan versiyasini (RFC 862) amalga oshiradi, bu mijoz tomonidan yuborilgan har qanday xabarning nusxasini qaytaradi.

echo iteration udp server

Ushbu va keyingi bo'limda biz echo xizmati uchun serverlar bilan tanishamiz. U 7-raqamli portda mavjud va UDP va TCP orqali ishlaydi (bu port zahiralangan, shuning uchun echo server administrator imtiyozlari bilan ishga tushirilishi kerak).

Echo UDP serveri doimiy ravishda datagrammalarni o'qiydi va ularning nusxasini jo'natuvchiga qaytaradi. Server bir vaqtning o'zida faqat bitta xabarni qayta ishlashi kerakligi sababli, bu erda iterativ arxitektura etarli bo'ladi. Serverlar uchun sarlavha fayli 56.1-XNUMX ro'yxatda ko'rsatilgan.

Ro'yxat 56.1. id_echo_sv.c va id_echo_cl.c dasturlari uchun sarlavha fayli

#include "inet_sockets.h" /* Soket funksiyalarimizni e'lon qiladi */
# "tlpi_hdr.h" ni o'z ichiga oladi

#define SERVICE "echo" /* UDP xizmat nomi */

#define BUF_SIZE 500 /* Datagramlarning maksimal hajmi
mijoz va server tomonidan o'qilishi mumkin */
______________________________________________________________________________ rozetkalar/id_echo.h

56.2-XNUMX ro'yxati serverning bajarilishini ko'rsatadi. Quyidagi fikrlarga e'tibor qaratish lozim:

  • serverni demon rejimiga o'tkazish uchun biz 37.2-bo'limdagi becomeDaemon() funksiyasidan foydalanamiz;

  • dasturni yanada ixcham qilish uchun biz 55.12 bo'limida ishlab chiqilgan internet domen soket kutubxonasidan foydalanamiz;

  • agar server mijozga javob qaytara olmasa, u syslog() chaqiruvi yordamida jurnalga xabar yozadi.

Haqiqiy dasturda biz syslog() yordamida xabarlarni yozish chastotasiga ma'lum bir cheklov qo'yishimiz mumkin. Bu tajovuzkorning tizim jurnalini to'ldirishi ehtimolini yo'q qiladi. Shuni ham yodda tutingki, har bir syslog() qo'ng'irog'i juda qimmat, chunki u sukut bo'yicha fsync() dan foydalanadi.

Ro'yxat 56.2. Echo UDP xizmatini amalga oshiradigan iteratsiya serveri

_________________________________________________________________rozetkalar/id_echo_sv.c
#o'z ichiga oladi
# "id_echo.h" ni kiriting
# "become_daemon.h" ni kiriting

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

agar (Daemon bo'l (0) == -1)
errExit("Daemonga aylanish");

sfd = inetBind (SERVICE, SOCK_DGRAM, NULL);
agar (sfd == -1) {
syslog(LOG_ERR, "Server soketini (%s) yaratib bo‘lmadi",
strerror (xato));
chiqish (EXIT_FAILURE);

/* Datagramlarni qabul qilish va ularning nusxalarini jo‘natuvchilarga qaytarish */
}
uchun(;;) {
len = sizeof (struct sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

agar (numRead == -1)
errExit("recvfrom");
agar (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
!=numRead)
syslog(LOG_WARNING, "%s (%s) ga javobni aks ettirishda xatolik yuz berdi",
inetAddressStr((struct sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror (xato));
}
}
_________________________________________________________________rozetkalar/id_echo_sv.c

Serverni sinab ko'rish uchun 56.3 ro'yxatidagi dasturdan foydalanamiz. Shuningdek, u 55.12-bo'limda ishlab chiqilgan Internet domen soket kutubxonasidan foydalanadi. Mijoz dasturi buyruq satrida birinchi argument sifatida server joylashgan tarmoq xosti nomini oladi. Mijoz halqaga kiradi, u erda qolgan argumentlarning har birini serverga alohida datagramlar sifatida yuboradi, so'ngra javob sifatida serverdan olingan datagrammalarni o'qiydi va chiqaradi.

Ro'yxat 56.3. Echo UDP xizmati uchun mijoz

# "id_echo.h" ni kiriting

int
asosiy (int argc, char *argv[])
{
int sfd, j;
size_tlen;
ssize_t numRead;
charbuf[BUF_SIZE];

agar (argc < 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s xost xabari…n", argv[0]);

/* Birinchi buyruq qatori argumenti asosida server manzilini yarating */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
agar (sfd == -1)
fatal("Server soketiga ulanib bo'lmadi");

/* Qolgan argumentlarni serverga alohida datagramlar sifatida yuboring */
uchun (j = 2; j < argc; j++) {
len = strlen(argv[j]);
agar (write(sfd, argv[j], len) != len)
halokatli ("qisman/muvaffaqiyatsiz yozish");

numRead = o'qish (sfd, buf, BUF_SIZE);
agar (numRead == -1)
errExit("o'qish");
printf("[%ld bayt] %.*sn", (uzun) numRead, (int) numRead, buf);
}
chiqish (EXIT_SUCCESS);
}
_________________________________________________________________rozetkalar/id_echo_cl.c

Quyida biz serverni va ikkita mijoz misolini ishga tushirganimizda ko'rishimiz mumkin bo'lgan misoldir:

$ su // Zaxiralangan portga ulanish uchun imtiyozlarni talab qiladi
Parol:
# ./id_echo_sv // Server fonga o'tadi
# chiqish // Administrator huquqlaridan voz kechish
$ ./id_echo_cl localhost salom dunyo // Bu mijoz ikkita datagramma yuboradi
[5 bayt] salom // Mijoz serverdan olingan javobni chiqaradi
[5 bayt] dunyo
$ ./id_echo_cl localhost xayr // Bu mijoz bitta datagram yuboradi
[7 bayt] xayr

Sizga yoqimli o'qish tilayman)

Manba: linux.org.ru