Книга Β«Linux API. Π˜ΡΡ‡Π΅Ρ€ΠΏΡ‹Π²Π°ΡŽΡ‰Π΅Π΅ руководство»


Книга «Linux API. Π˜ΡΡ‡Π΅Ρ€ΠΏΡ‹Π²Π°ΡŽΡ‰Π΅Π΅ руководство»

Π”ΠΎΠ±Ρ€Ρ‹ΠΉ дСнь! ΠŸΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ Π²Π°ΡˆΠ΅ΠΌΡƒ вниманию ΠΊΠ½ΠΈΠ³Ρƒ «Linux API. Π˜ΡΡ‡Π΅Ρ€ΠΏΡ‹Π²Π°ΡŽΡ‰Π΅Π΅ руководство»(ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ ΠΊΠ½ΠΈΠ³ΠΈ The Linux Programming Interface). Π•Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΊΠ°Π·Π°Ρ‚ΡŒ Π½Π° сайтС ΠΈΠ·Π΄Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π°, ΠΈ Ссли ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΌΠΎΠΊΠΎΠ΄ LinuxAPI , Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ скидку 30%.

ΠžΡ‚Ρ€Ρ‹Π²ΠΎΠΊ ΠΈΠ· ΠΊΠ½ΠΈΠ³ΠΈ для ознакомлСния:

Π‘ΠΎΠΊΠ΅Ρ‚Ρ‹: Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° сСрвСра

Π’ этой Π³Π»Π°Π²Π΅ ΠΌΡ‹ обсудим основы проСктирования ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… ΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… сСрвСров, Π° Ρ‚Π°ΠΊΠΆΠ΅ рассмотрим ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π΄Π΅ΠΌΠΎΠ½ inetd, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ созданиС сСрвСрных ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.

Π˜Ρ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ ΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Π΅ сСрвСры

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π΄Π²Π΅ распространСнныС Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ сСтСвых сСрвСров Π½Π° основС сокСтов:

  • итСрационная: сСрвСр обслуТиваСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ, сначала обрабатывая запрос (ΠΈΠ»ΠΈ нСсколько запросов) ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ Π·Π°Ρ‚Π΅ΠΌ пСрСходя ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ;

  • ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Π°Ρ: сСрвСр спроСктирован для обслуТивания Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ.

Π’ Ρ€Π°Π·Π΄Π΅Π»Π΅ 44.8 ΡƒΠΆΠ΅ Π±Ρ‹Π» прСдставлСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ сСрвСра Π½Π° основС ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ FIFO.

Π˜Ρ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ сСрвСры ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ подходят Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ситуациях, ΠΊΠΎΠ³Π΄Π° клиСнтскиС запросы ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ достаточно быстро, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π²Ρ‹Π½ΡƒΠΆΠ΄Π΅Π½ ΠΆΠ΄Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° Π½Π΅ обслуТат Π»ΡŽΠ±Ρ‹Ρ… Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², находящихся ΠΏΠ΅Ρ€Π΅Π΄ Π½ΠΈΠΌ. ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ сцСнариСм использования этого ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° являСтся ΠΎΠ±ΠΌΠ΅Π½ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹ΠΌΠΈ запросами ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π°ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром.

ΠŸΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Π΅ сСрвСры подходят Π² случаях, ΠΊΠΎΠ³Π΄Π° Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ запроса ΡƒΡ…ΠΎΠ΄ΠΈΡ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ количСство Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈΠ»ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ сСрвСр Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΠΌΠ΅Π½ сообщСниями. Π’ Π΄Π°Π½Π½ΠΎΠΉ Π³Π»Π°Π²Π΅ ΠΌΡ‹ Π² основном сосрСдоточимся Π½Π° Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎΠΌ (ΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ простом) способС проСктирования ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… сСрвСров, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ состоит Π² создании ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π’Π°ΠΊΠΎΠΉ процСсс выполняСт всю Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎ ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°Π½ΠΈΡŽ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, послС Ρ‡Π΅Π³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· этих процСссов Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΡƒΠ΅Ρ‚ нСзависимо, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ нСсколько ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. Основная Π·Π°Π΄Π°Ρ‡Π° Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ сСрвСрного процСсса (родитСля) Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² создании ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° (ΠΊΠ°ΠΊ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, вмСсто процСссов ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ выполнСния).

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Ρ€Π°Π·Π΄Π΅Π»Π°Ρ… ΠΌΡ‹ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ сСрвСров Π½Π° основС сокСтов ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-Π΄ΠΎΠΌΠ΅Π½Π°. Π­Ρ‚ΠΈ Π΄Π²Π° сСрвСра Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ слуТбы echo (RFC 862), которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ копию любого сообщСния, посланного Π΅ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ.

Π˜Ρ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ UDP-сСрвСр echo

Π’ этом ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ прСдставим сСрвСры для слуТбы echo. Она доступна Π½Π° ΠΏΠΎΡ€Ρ‚Π΅ с Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ 7 ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ ΠΏΠΎ UDP, Ρ‚Π°ΠΊ ΠΈ ΠΏΠΎ TCP (Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚ Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½, Π² связи с Ρ‡Π΅ΠΌ сСрвСр echo Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ с привилСгиями администратора).

UDP-сСрвСр echo постоянно считываСт Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚Π΅Π»ΡŽ ΠΈΡ… ΠΊΠΎΠΏΠΈΠΈ. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сСрвСру Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ сообщСниС Π·Π° Ρ€Π°Π·, здСсь Π±ΡƒΠ΄Π΅Ρ‚ достаточно ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» для сСрвСров ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² листингС 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 /* ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅
ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром */
____________________________________________________________________sockets/id_echo.h

Π’ листингС 56.2 прСдставлСна рСализация сСрвСра. Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹:

  • для ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° сСрвСра Π² Ρ€Π΅ΠΆΠΈΠΌ Π΄Π΅ΠΌΠΎΠ½Π° ΠΌΡ‹ задСйствуСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ becomeDaemon() ΠΈΠ· Ρ€Π°Π·Π΄Π΅Π»Π° 37.2;

  • Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½ΠΎΠΉ, ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сокСтами ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-Π΄ΠΎΠΌΠ΅Π½Π°, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΡƒΡŽ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 55.12;

  • Ссли сСрвСр Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ, Ρ‚ΠΎ записываСт сообщСниС Π² ΠΆΡƒΡ€Π½Π°Π», примСняя Π²Ρ‹Π·ΠΎΠ² syslog().

Π’ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΡ‹ Π±Ρ‹, скорСС всСго, Π²Π²Π΅Π»ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π½Π° частоту записи сообщСний с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ syslog(). Π­Ρ‚ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΎ Π±Ρ‹ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ пСрСполнСния систСмного ΠΆΡƒΡ€Π½Π°Π»Π° Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠΎΠΌ. К Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Π½Π΅ стоит Π·Π°Π±Ρ‹Π²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² syslog() довольно Π·Π°Ρ‚Ρ€Π°Ρ‚Π½Ρ‹ΠΉ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ fsync().

Листинг 56.2. Π˜Ρ‚Π΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ сСрвСр, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ UDP-слуТбу echo

_________________________________________________________________sockets/id_echo_sv.c
#include <syslog.h>
#include "id_echo.h"
#include "become_daemon.h"

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

if (becomeDaemon(0) == -1)
errExit("becomeDaemon");

sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);
if (sfd == -1) {
syslog(LOG_ERR, "Could not create server socket (%s)",
strerror(errno));
exit(EXIT_FAILURE);

/* ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ отправитСлям ΠΈΡ… ΠΊΠΎΠΏΠΈΠΈ */
}
for (;;) {
len = sizeof(struct sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

if (numRead == -1)
errExit("recvfrom");
if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
!= numRead)
syslog(LOG_WARNING, "Error echoing response to %s (%s)",
inetAddressStr((struct sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror(errno));
}
}
_________________________________________________________________sockets/id_echo_sv.c

Для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈΠ· листинга 56.3. Π’ Π½Π΅ΠΉ Ρ‚ΠΎΠΆΠ΅ примСняСтся Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сокСтами ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-Π΄ΠΎΠΌΠ΅Π½Π°, разработанная Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 55.12. Π’ качСствС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки клиСнтская ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ имя сСтСвого ΡƒΠ·Π»Π°, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ находится сСрвСр. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ†ΠΈΠΊΠ», Π³Π΄Π΅ отправляСт сСрвСру ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π² Π²ΠΈΠ΄Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌ, Π° Π·Π°Ρ‚Π΅ΠΌ считываСт ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ ΠΎΡ‚ сСрвСра Π² ΠΎΡ‚Π²Π΅Ρ‚.

Листинг 56.3. ΠšΠ»ΠΈΠ΅Π½Ρ‚ для UDP-слуТбы echo

#include "id_echo.h"

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

if (argc < 2 || strcmp(argv[1], "—help") == 0)
usageErr("%s host msg…n", argv[0]);

/* Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ адрСс сСрвСра Π½Π° основС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
if (sfd == -1)
fatal("Could not connect to server socket");

/* ΠŸΠΎΡΡ‹Π»Π°Π΅ΠΌ сСрвСру ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π² Π²ΠΈΠ΄Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌ */
for (j = 2; j < argc; j++) {
len = strlen(argv[j]);
if (write(sfd, argv[j], len) != len)
fatal("partial/failed write");

numRead = read(sfd, buf, BUF_SIZE);
if (numRead == -1)
errExit("read");
printf("[%ld bytes] %.*sn", (long) numRead, (int) numRead, buf);
}
exit(EXIT_SUCCESS);
}
_________________________________________________________________sockets/id_echo_cl.c

НиТС ΠΏΠΎΠΊΠ°Π·Π°Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ ΠΏΡ€ΠΈ запускС сСрвСра ΠΈ Π΄Π²ΡƒΡ… экзСмпляров ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:

$ su // Для привязки ΠΊ Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌΡƒ ΠΏΠΎΡ€Ρ‚Ρƒ Π½ΡƒΠΆΠ½Ρ‹ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΈ
Password:
# ./id_echo_sv // Π‘Π΅Ρ€Π²Π΅Ρ€ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ„ΠΎΠ½ΠΎΠ²Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ
# exit // ΠžΡ‚ΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌΡΡ ΠΎΡ‚ ΠΏΡ€Π°Π² администратора
$ ./id_echo_cl localhost hello world // Π­Ρ‚ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт Π΄Π²Π΅ Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹
[5 bytes] hello // ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΎΡ‚Π²Π΅Ρ‚, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ ΠΎΡ‚ сСрвСра
[5 bytes] world
$ ./id_echo_cl localhost goodbye // Π­Ρ‚ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΡˆΠ»Π΅Ρ‚ ΠΎΠ΄Π½Ρƒ Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΌΡƒ
[7 bytes] goodbye

Π–Π΅Π»Π°ΡŽ приятного чтСния)

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: linux.org.ru