Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² срСдС Linux. Π’Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 91

Автор Майкл ДТонсон

17.3.2. Установка соСдинСний

ПослС создания ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠ³ΠΎ сокСта Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ ΠΊ Ρ‡Π΅ΠΌΡƒ-Ρ‚ΠΎ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΌΡƒ. Установка соСдинСний сокСтов являСтся Π² большой стСпСни нСсиммСтричной Π·Π°Π΄Π°Ρ‡Π΅ΠΉ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ каТдая сторона ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ соСдинСниС ΠΏΠΎ-Ρ€Π°Π·Π½ΠΎΠΌΡƒ. Одна сторона ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ сокСт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π³ΠΎΡ‚ΠΎΠ² ΠΊ соСдинСнию, ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΊ Π½Π΅ΠΌΡƒ. Π­Ρ‚Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ сСрвСрныС прилоТСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ΄Π½Π°ΠΆΠ΄Ρ‹ Π°ΠΊΡ‚ΠΈΠ²ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ постоянно ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, оТидая ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ со стороны Π΄Ρ€ΡƒΠ³ΠΈΡ… процСссов.

ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠΈΠ΅ процСссы, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΡΠΎΠ·Π΄Π°ΡŽΡ‚ сокСт, ΡΠΎΠΎΠ±Ρ‰Π°ΡŽΡ‚ систСмС адрСс, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ½ΠΈ хотят ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ, ΠΈ послС этого ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сСрвСр (ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°) ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΡƒ соСдинСния, устанавливаСтся соСдинСниС ΠΌΠ΅ΠΆΠ΄Ρƒ двумя сокСтами. ПослС этого сокСт ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для двустороннСй связи.

17.3.3. БвязываниС адрСса с сокСтом

И сСрвСрный, ΠΈ клиСнтский процСссы Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ систСмС, ΠΊΠ°ΠΊΠΎΠΉ адрСс ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для сокСта. ΠŸΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»Π΅Π½ΠΈΠ΅ адрСса ΠΊ локальной сторонС сокСта называСтся связываниСм сокСта ΠΈ выполняСтся Ρ‡Π΅Ρ€Π΅Π· систСмный Π²Ρ‹Π·ΠΎΠ² bind().

#include <sys/socket.h>


int bind(int sock, struct sockaddr * my_addr, socklen_t addrlen);

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” это связываСмый сокСт, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π·Π°Π΄Π°ΡŽΡ‚ адрСс для локальной ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ.

17.3.4. ОТиданиС соСдинСний

ПослС создания сокСта сСрвСр привязываСт ΠΊ Π½Π΅ΠΌΡƒ адрСс с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bind(). Π”Π°Π»Π΅Π΅ процСсс сообщаСт систСмС ΠΏΡƒΡ‚Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ listen(), Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π³ΠΎΡ‚ΠΎΠ² Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссам соСдинСниС с Π΄Π°Π½Π½Ρ‹ΠΌ сокСтом (ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ адрСсу). Если сокСт привязан ΠΊ адрСсу, ядро ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ соСдинСния с Π΄Π°Π½Π½Ρ‹ΠΌ адрСсом, ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠ΅ ΠΎΡ‚ процСссов. Однако соСдинСниС Π½Π΅ устанавливаСтся Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. Π‘Π»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ процСсс сначала Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ³Π»Π°ΡΠΈΡ‚ΡŒΡΡ с ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΎΠΉ соСдинСния Ρ‡Π΅Ρ€Π΅Π· систСмный Π²Ρ‹Π·ΠΎΠ² accept(). Π”ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° новая ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° соСдинСния с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ адрСсом Π½Π΅ принята, ΠΎΠ½Π° называСтся ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΌ соСдинСниСм.

Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, функция accept() блокируСтся Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΊ Π½Π΅ΠΉ Π½Π΅ пытаСтся ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ клиСнтский процСсс. Если сокСт Π±Ρ‹Π» ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½ ΠΊΠ°ΠΊ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ‡Π΅Ρ€Π΅Π· fcntl(), Ρ‚ΠΎ функция accept() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ EAGAIN Π² Ρ‚ΠΎΠΌ случаС, Ссли Π½Π΅Ρ‚ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ доступного клиСнтского процСсса[120]. БистСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹ select(), poll() ΠΈ epoll ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для указания, ΠΆΠ΄Π°Ρ‚ΡŒ Π»ΠΈ соСдинСнию ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ (эти Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΏΠΎΠΌΠ΅Ρ‡Π°ΡŽΡ‚ сокСт ΠΊΠ°ΠΊ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ для считывания)[121].

НиТС ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΡ‹ listen() ΠΈ accept().

#include <sys/socket.h>


int listen(int sock, int backlog);

int accept(int sock, struct sockaddr * addr, socklen_t * addrlen);

Π’ ΠΎΠ±Π΅ΠΈΡ… функциях прСдполагаСтся, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” это Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор. Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ backlog Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ listen() Π·Π°Π΄Π°Π΅Ρ‚ максимальноС количСство соСдинСний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π½Π° Π΄Π°Π½Π½ΠΎΠΌ сокСтС. Π‘Π΅Ρ‚Π΅Π²Ρ‹Π΅ соСдинСния Π½Π΅ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° сСрвСр Π½Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ‚ соСдинСниС Ρ‡Π΅Ρ€Π΅Π· accept(); всС входящиС соСдинСния ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ приостановлСнными. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ нСбольшоС количСство ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… соСдинСний Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ядро Ρ‚Π΅ΠΌ самым освобоТдаСт сСрвСрныС процСссы ΠΎΡ‚ нСобходимости Π±Ρ‹Ρ‚ΡŒ Π² постоянной готовности ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ соСдинСния. Π˜ΡΡ‚ΠΎΡ€ΠΈΡ‡Π΅ΡΠΊΠΈ принято ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒ Π² прилоТСниях количСство Π½Π΅Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… Π·Π°Π΄Π°Π½ΠΈΠΉ ΠΏΡΡ‚ΡŒΡŽ, хотя ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ большСС количСство. Ѐункция listen() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ноль Π² случаС успСха ΠΈ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ число Π² случаС Π½Π΅ΡƒΠ΄Π°Ρ‡ΠΈ.

Π’Ρ‹Π·ΠΎΠ² accept() ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ соСдинСниС Π² установлСнноС. УстановлСнноС соСдинСниС ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ функция accept(). Новый дСскриптор наслСдуСт всС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ Ρ‚ΠΎΠ³ΠΎ сокСта, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΎΠ±Ρ€Π°Ρ‰Π°Π»Π°ΡΡŒ функция listen(). НСобычноС свойство accept() состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ сСтСвыС ошибки, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, ΠΊΠ°ΠΊ ошибки принятия ΠΎΡ‚ accept()[122]. ΠŸΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ ошибки сСрвСры Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ errno ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ: ECONNABORTED, ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP ΠΈΠ»ΠΈ ENETUNREACH. ВсС эти ошибки Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, просто Π²Ρ‹Π·Π²Π°Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept() Π½Π° сСрвСрС Π΅Ρ‰Π΅ Ρ€Π°Π·.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ addr ΠΈ addrlen ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π΄Π°Π½Π½Ρ‹Π΅, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ядро Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ адрСс ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ (клиСнтского) ΠΊΠΎΠ½Ρ†Π° соСдинСния. Π’ исходном состоянии addrlen прСдставляСт собой Ρ†Π΅Π»ΠΎΠ΅ число, содСрТащСС Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π°, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ссылаСтся addr. Ѐункция accept() Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ open() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор ΠΈΠ»ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ссли Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка.

17.3.5. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ сСрвСру

Как ΠΈ сСрвСры, ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ сразу послС создания сокСта ΡΠ²ΡΠ·Ρ‹Π²Π°Ρ‚ΡŒ с Π½ΠΈΠΌ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ адрСс. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ пропускаСт этот шаг, прСдоставляя ядру ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ сокСту любой подходящий Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ адрСс.

ПослС этапа связывания (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, Π²ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½) ΠΊΠ»ΠΈΠ΅Π½Ρ‚ соСдиняСтся с сСрвСром Ρ‡Π΅Ρ€Π΅Π· систСмный Π²Ρ‹Π·ΠΎΠ² connect().

#include <sys/socket.h>


int connect(int sock, struct sockaddr * servaddr, socklen_t addrlen);

ΠŸΡ€ΠΎΡ†Π΅ΡΡ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ, ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡΡΡŒ адрСса, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ сокСт.

На рис. 17.1 ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для установки соСдинСний сокСтов, ΠΈ порядок, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ.

Рис 17.1. Установка соСдинСний сокСтов

17.3.6. Поиск адрСсов соСдинСния

ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ соСдинСниС установлСно, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΉΡ‚ΠΈ адрСса ΠΊΠ°ΠΊ ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ, Ρ‚Π°ΠΊ ΠΈ локального ΠΊΠΎΠ½Ρ†ΠΎΠ² сокСта с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ getpeername() ΠΈ getsockname().

#include <sys/socket.h>


int getpeername(int s, struct sockaddr * addr, socklen_t * addrlen);

int getsockname(int s, struct sockaddr * addr, socklen_t * addrlen);

ОбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ адрСса соСдинСний сокСта s Π² Ρ‚Π΅ структуры, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ addr. АдрСс ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΉ стороны возвращаСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ getpeername(), Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ getsockname() сообщаСт адрСс локальной части соСдинСния. Для ΠΎΠ±Π΅ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π² качСствС ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ цСлочислСнного значСния, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ addrlen, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ установлСн Ρ€Π°Π·ΠΌΠ΅Ρ€ пространства, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ выдСляСтся ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ addr. Π­Ρ‚ΠΎ Ρ†Π΅Π»ΠΎΠ΅ число замСняСтся количСством Π±Π°ΠΉΡ‚ Π² Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠΌ адрСсС.

17.4. Π‘ΠΎΠΊΠ΅Ρ‚Ρ‹ Π΄ΠΎΠΌΠ΅Π½Π° Unix

Π‘ΠΎΠΊΠ΅Ρ‚Ρ‹ Π΄ΠΎΠΌΠ΅Π½Π° Unix β€” это ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π΅ сСмСйство ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ², доступноС Ρ‡Π΅Ρ€Π΅Π· API- интСрфСйс сокСтов. Они фактичСски Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ сСтСвыми ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°ΠΌΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΎΠ΅Π΄ΠΈΠ½ΡΡ‚ΡŒΡΡ с сокСтами Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΠΈ Ρ‚ΠΎΠΌ ΠΆΠ΅ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅. НСсмотря Π½Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ это Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΈΡ… ΠΏΠΎΠ»Π΅Π·Π½ΠΎΡΡ‚ΡŒ, ΠΎΠ½ΠΈ всС ΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΌΠ½ΠΎΠ³ΠΈΠΌΠΈ прилоТСниями благодаря Π³ΠΈΠ±ΠΊΠΎΠΌΡƒ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡƒ IPC, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ½ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚. Π˜Ρ… адрСса β€” это ΠΏΡƒΡ‚Π΅Π²Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС, ΠΊΠΎΠ³Π΄Π° сокСт привязываСтся ΠΊ ΠΏΡƒΡ‚Π΅Π²ΠΎΠΌΡƒ ΠΈΠΌΠ΅Π½ΠΈ. Π€Π°ΠΉΠ»Ρ‹ сокСтов, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ адрСса Π΄ΠΎΠΌΠ΅Π½ΠΎΠ² Unix, ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡƒΡ‰Π΅Π½Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ stat(), Π½ΠΎ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ open(); вмСсто этого Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ API сокСтов.

Π”ΠΎΠΌΠ΅Π½ Unix прСдусматриваСт ΠΊΠ°ΠΊ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅, Ρ‚Π°ΠΊ ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Π΅ интСрфСйсы. Π”Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ интСрфСйс ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ€Π΅Π΄ΠΊΠΎ, ΠΈ здСсь ΠΎΠ±ΡΡƒΠΆΠ΄Π°Ρ‚ΡŒΡΡ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚. ΠœΡ‹ рассмотрим ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ интСрфСйс, Ρ€Π°Π±ΠΎΡ‚Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½Π° ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΠΊΠ°Π½Π°Π»Π°ΠΌ. ΠŸΡ€ΠΈ этом сокСты Π΄ΠΎΠΌΠ΅Π½Π° Unix, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π½Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΠΊΠ°Π½Π°Π»Π°ΠΌ.

Если нСсколько процСссов ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠ°Π½Π°Π», Ρ‚ΠΎ любой ΠΈΠ· Π½ΠΈΡ… ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΡ‡Π΅ΡΡ‚ΡŒ сообщСниС, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ΅ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ°Π½Π°Π» Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссом. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ°Π½Π°Π» ΠΏΠΎΡ…ΠΎΠΆ Π½Π° доску объявлСний. Если процСсс располагаСт сообщСниС Π½Π° доскС, Ρ‚ΠΎ любой Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс (с достаточными полномочиями) ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ это сообщСниС с доски.

Π‘ΠΎΠΊΠ΅Ρ‚Ρ‹ Π΄ΠΎΠΌΠ΅Π½Π° Unix Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π½Π° основС соСдинСний; Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ соСдинСния с сокСтом Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠ°Π½Π°Π» связи. Π‘Π΅Ρ€Π²Π΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ мноТСство соСдинСний ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, сохраняСт для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ… свой Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор. Благодаря этому свойству сокСты Π΄ΠΎΠΌΠ΅Π½Π° Unix Π»ΡƒΡ‡ΡˆΠ΅ подходят для выполнСния ΠΌΠ½ΠΎΠ³ΠΈΡ… Π·Π°Π΄Π°Ρ‡ IPC, Ρ‡Π΅ΠΌ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΊΠ°Π½Π°Π»Ρ‹. Π­Ρ‚ΠΎ главная ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΎΠ½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎΠΌ стандартных слуТб Linux, Π²ΠΊΠ»ΡŽΡ‡Π°Π» X Window System ΠΈ систСмный рСгистратор.

17.4.1. АдрСса Π΄ΠΎΠΌΠ΅Π½Π° Unix

АдрСса для сокСтов Π΄ΠΎΠΌΠ΅Π½Π° Unix ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΡƒΡ‚Π΅Π²Ρ‹ΠΌΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС. Если Ρ„Π°ΠΉΠ» Π΅Ρ‰Π΅ Π½Π΅ сущСствуСт, Ρ‚ΠΎ ΠΎΠ½ создаСтся ΠΊΠ°ΠΊ Ρ„Π°ΠΉΠ» сокСтного Ρ‚ΠΈΠΏΠ° Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° сокСт привязываСтся ΠΊ ΠΏΡƒΡ‚Π΅Π²ΠΎΠΌΡƒ ΠΈΠΌΠ΅Π½ΠΈ Ρ‡Π΅Ρ€Π΅Π· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ bind(). Если ΡƒΠΆΠ΅ сущСствуСт Ρ„Π°ΠΉΠ» (ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ сокСт) с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ ΠΏΡƒΡ‚Π΅Π²Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‚ΠΎ функция bind() Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ EADDRINUSE, bind() устанавливаСт ΠΏΡ€Π°Π²Π° доступа для созданного Ρ„Π°ΠΉΠ»Π° сокСта Ρ€Π°Π²Π½Ρ‹ΠΌΠΈ 0666, ΠΊΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ маской umask.