පොත "ලිනක්ස් API. විස්තීරණ මාර්ගෝපදේශය"


පොත "ලිනක්ස් API. විස්තීරණ මාර්ගෝපදේශය"

සුභ සන්ධ්යාවක් මම ඔබේ අවධානයට “ලිනක්ස් ඒපීඅයි” පොත ඉදිරිපත් කරමි. විස්තීරණ මාර්ගෝපදේශයක්" (පොත පරිවර්තනය ලිනක්ස් ක්‍රමලේඛන අතුරු මුහුණත) එය ප්‍රකාශකයාගේ වෙබ් අඩවියෙන් ඇණවුම් කළ හැකි අතර, ඔබ ප්‍රවර්ධන කේතය යොදන්නේ නම් LinuxAPI , ඔබට 30% ක වට්ටමක් ලැබෙනු ඇත.

පරිශීලනය සඳහා පොතෙන් උපුටා ගැනීම:

Sockets: Server Architecture

මෙම පරිච්ඡේදයේදී, අපි පුනරාවර්තන සහ සමාන්තර සේවාදායකයන් සැලසුම් කිරීමේ මූලික කරුණු සාකච්ඡා කරනු ඇති අතර, අන්තර්ජාල සේවාදායක යෙදුම් නිර්මාණය කිරීම පහසු කරන 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 වැඩසටහන් සඳහා ශීර්ෂ ගොනුව

#ඇතුළත් "inet_sockets.h" /* අපගේ සොකට් එකේ කාර්යයන් ප්‍රකාශ කරයි */
#"tlpi_hdr.h" ඇතුලත් කරන්න

#SERVICE "echo" නිර්වචනය කරන්න /* UDP සේවා නාමය */

#BUF_SIZE 500 /* උපරිම දත්ත ග්‍රෑම් ප්‍රමාණය නිර්වචනය කරන්න
සේවාදායකයා සහ සේවාදායකය විසින් කියවිය හැක */
____________________________________________________________________________________sockets/id_echo.h

56.2 ලැයිස්තුගත කිරීම සේවාදායකය ක්‍රියාත්මක කිරීම පෙන්වයි. පහත සඳහන් කරුණු සැලකිල්ලට ගැනීම වටී:

  • සේවාදායකය ඩීමන් ප්‍රකාරයට දැමීම සඳහා, අපි 37.2 කොටසේ සිට beDaemon() ශ්‍රිතය භාවිතා කරමු;

  • වැඩසටහන වඩාත් සංයුක්ත කිරීම සඳහා, අපි 55.12 වගන්තියේ සංවර්ධනය කරන ලද අන්තර්ජාල වසම් සොකට් සමඟ වැඩ කිරීම සඳහා පුස්තකාලය භාවිතා කරමු;

  • සේවාදායකයාට සේවාදායකයාට ප්‍රතිචාරයක් ලබා දිය නොහැකි නම්, එය syslog() ඇමතුම භාවිතයෙන් ලොගයට පණිවිඩයක් ලියයි.

සැබෑ යෙදුමක, අපි syslog() භාවිතයෙන් පණිවිඩ ලොග් වීමේ වාර ගණනට යම් සීමාවක් පැනවීමට ඉඩ ඇත. මෙය ප්‍රහාරකයෙකු විසින් පද්ධති ලොගය පිටාර ගැලීමේ හැකියාව ඉවත් කරනු ඇත. මීට අමතරව, පෙරනිමියෙන් fsync() භාවිතා කරන බැවින්, syslog() සඳහා වන සෑම ඇමතුමක්ම තරමක් මිල අධික බව අමතක නොකරන්න.

ලැයිස්තුගත කිරීම 56.2. UDP echo සේවාව ක්‍රියාත්මක කරන පුනරාවර්තන සේවාදායකය

_____________________________________________________________________________ සොකට්/id_echo_sv.c
#ඇතුළත්
#"id_echo.h" ඇතුලත් කරන්න
#ඇතුළත් "become_daemon.h"

int
ප්‍රධාන (int argc, char *argv[])
{
int sfd;
ssize_t numRead;
socklen_t len;
ව්‍යුහාත්මක sockaddr_storage claddr;
char buf[BUF_SIZE];
char addrStr[IS_ADDR_STR_LEN];

නම් (becomeDaemon(0) == -1)
errExit ("becomeDaemon");

sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);
නම් (sfd == -1) {
syslog(LOG_ERR, "සේවාදායක සොකට් (%s) තැනීමට නොහැකි විය",
strerror (errno));
පිටවීම (EXIT_FAILURE);

/* දත්ත සටහන් ලබාගෙන ඒවායේ පිටපත් යවන්නන් වෙත ආපසු ලබා දෙන්න */
}
සදහා (;;) {
ලෙන් = ප්‍රමාණය (ව්‍යුහය 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 (errno));
}
}
_____________________________________________________________________________ සොකට්/id_echo_sv.c

සේවාදායකයේ ක්‍රියාකාරිත්වය පරීක්ෂා කිරීම සඳහා, අපි ලැයිස්තුගත කිරීම 56.3 වෙතින් වැඩසටහන භාවිතා කරමු. එය 55.12 වගන්තියේ සංවර්ධනය කරන ලද අන්තර්ජාල වසම් සොකට් සමඟ වැඩ කිරීම සඳහා පුස්තකාලය ද භාවිතා කරයි. පළමු විධාන රේඛා තර්කය ලෙස, සේවාදායක වැඩසටහන සේවාදායකය පිහිටා ඇති ජාල නෝඩයේ නම ගනී. සේවාදායකයා ලූපයකට ඇතුළු වන අතර එහිදී ඉතිරි එක් එක් තර්ක වෙනම දත්ත ග්‍රෑම් ලෙස සේවාදායකයට යවන අතර පසුව ප්‍රතිචාර වශයෙන් සේවාදායකයෙන් ලැබෙන දත්ත ග්‍රෑම් කියවා මුද්‍රණය කරයි.

ලැයිස්තුගත කිරීම 56.3. UDP echo සේවාව සඳහා සේවාදායකයා

#"id_echo.h" ඇතුලත් කරන්න

int
ප්‍රධාන (int argc, char *argv[])
{
int sfd, j;
ප්‍රමාණය_t ලෙන්;
ssize_t numRead;
char buf[BUF_SIZE];

නම් (argc < 2 || strcmp(argv[1], "--help") == 0)
UseErr("%s host msg...n", argv[0]);

/* පළමු විධාන රේඛා තර්කය මත පදනම්ව සේවාදායක ලිපිනය සාදන්න */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
නම් (sfd == -1)
මාරක ("සේවාදායක සොකට් වෙත සම්බන්ධ විය නොහැක");

/* ඉතිරි තර්ක වෙනම දත්ත ග්‍රෑම් ආකාරයෙන් සේවාදායකයට යවන්න */
සඳහා (j = 2; j < argc; j++) {
ලෙන් = strlen (argv[j]);
නම් (ලියන්න(sfd, argv[j], len) != len)
මාරක ("අර්ධ/අසාර්ථක ලිවීම");

numRead = කියවීම (sfd, buf, BUF_SIZE);
නම් (numRead == -1)
ErrExit ("කියවන්න");
printf("[%ld bytes] %.*sn", (දිගු) numRead, (int) numRead, buf);
}
පිටවීම (EXIT_SUCCESS);
}
________________________________________________________________________________ සොකට්/id_echo_cl.c

පහත දැක්වෙන්නේ සේවාදායකය ක්‍රියාත්මක කිරීමේදී අප දකින දේ සහ සේවාදායක අවස්ථා දෙකක් සඳහා උදාහරණයකි:

$su // වෙන් කළ තොටකට බැඳීමට වරප්‍රසාද අවශ්‍ය වේ
මුරපදය:
# ./id_echo_sv // සේවාදායකය පසුබිම් මාදිලියට යයි
# පිටවීම // පරිපාලක අයිතිවාසිකම් අත්හරින්න
$ ./id_echo_cl localhost hello world // මෙම සේවාදායකයා Datagrams දෙකක් යවයි
[5 bytes] hello // සේවාදායකයා සේවාදායකයෙන් ලැබෙන ප්‍රතිචාරය පෙන්වයි
[බයිට් 5] ලෝකය
$ ./id_echo_cl localhost සමුගැනීම // මෙම සේවාදායකයා එක් දත්ත ග්‍රෑම් එකක් යවයි
[බයිට් 7] ආයුබෝවන්

මම ඔබට ප්‍රසන්න කියවීමක් ප්‍රාර්ථනා කරමි)

මූලාශ්රය: linux.org.ru