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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Linux: ПолноС руководство». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 151

Автор ДСнис ΠšΠΎΠ»ΠΈΡΠ½ΠΈΡ‡Π΅Π½ΠΊΠΎ

Ѐункция getsockopt() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. ΠšΡ€ΠΎΠΌΠ΅ Π²Ρ‹ΡˆΠ΅ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², функция getsockopt() ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹:

♦ SO_ERROR β€” Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠΌΠ΅Ρ€ ошибки (Π±ΡƒΠ΄Π΅Ρ‚ Π² Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ);

♦ SO_TYPE β€” Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΈΠΏ сокСта.

Рассмотрим нСбольшой ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с опциями сокСтов. ΠœΡ‹ установим Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° TCP.

#include "sock.h"

#include "stdio.h"


main() {

 int sd; /* дСскриптор сокСта */

 int optval; /* Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠΏΡ†ΠΈΠΈ */

 int optlen; /* Π΄Π»ΠΈΠ½Π° optval */

 int new_buffsize = 8192; /* Π½ΠΎΠ²Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° */


 /* создаСм сокСт */

 sd = socket(AF_INET, SOCK_STREAM, 0);

 /* считываниС Π΄Π»ΠΈΠ½Ρ‹ Π±ΡƒΡ„Π΅Ρ€Π° TCP */

 optlen = sizeof(optval);

 getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen);

 printf("Size of send buffer %d\n", optval);

 getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);

 printf("Size of recv buffer %d\n", optval);

 /* измСняСм Π΄Π»ΠΈΠ½Ρƒ Π±ΡƒΡ„Π΅Ρ€Π° */

 setsockopt(sd, SOL_SOCKET, SO_RCVBUF,

  &new_buffsize, sizeof(new_buffsize));

 setsockopt(sd, SOL_SOCKET, SO_SNDBUF,

  &new_buffsize, sizeof(new_buffsize));

 /* Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ */

 getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen);

 printf("New size of send buffer %d\n", optval);

 getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);

 printf("New size of recv buffer %d\n", optval);

}

27.3.10. Π‘ΠΈΠ³Π½Π°Π»Ρ‹ ΠΈ сокСты

Π‘ сокСтами связаны Ρ‚Ρ€ΠΈ сигнала:

♦ SIGIO β€” сокСт Π³ΠΎΡ‚ΠΎΠ² ΠΊ Π²Π²ΠΎΠ΄Ρƒ/Π²Ρ‹Π²ΠΎΠ΄Ρƒ. Π‘ΠΈΠ³Π½Π°Π» посылаСтся процСссу, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ связан с сокСтом;

♦ SIGURG β€” сокСт ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» экспрСсс-Π΄Π°Π½Π½Ρ‹Π΅ (ΠΌΡ‹ ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ, поэтому особо ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Π½ΠΈΡ… Π½Π΅Ρ‚ смысла);

♦ SIGPIPE β€” запись Π² сокСт большС Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°. Π‘ΠΈΠ³Π½Π°Π» посылаСтся процСссу, связанному с сокСтом. НапримСр, функция write() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ сигнал SIGPIPE, Ссли ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ процСсс Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ ΠΈΠ»ΠΈ связь ΠΏΠΎ сСти Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сигнала SIGPIPE ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π½ΠΈΠΆΠ΅.

Листинг 27.6. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сигнала SIGPIPE

#include "sock.h"

#include <signal.h>


/* ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала SIGPIPE */

sigpipe_handler() {

 err_quit("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ SIGPIPE \n");

}


main() {

 int sock; /* дСскриптор сокСта */

 /* установка ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала SIGPIPE */

 signal(SIGPIPE, sigpipe_handler);

 /* Ρ€Π°Π±ΠΎΡ‚Π° с сокСтом */

}

27.3.11. ΠœΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

Π’ этой Π³Π»Π°Π²Π΅ ΠΌΡ‹ рассматривали ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹-сСрвСра, ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ запросы Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ всС выглядит Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ слоТнСС: сСрвСру приходится ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ запросы ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². Для ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ запросов ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ систСмный Π²Ρ‹Π·ΠΎΠ² select(). Π­Ρ‚ΠΎΡ‚ Π²Ρ‹Π·ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, супСрсСрвСр xinetd.

Листинг 27.7. ΠœΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ запросов

#include "sock.h"

#include <sys/time.h>


main() {

 int sock; /* дСскриптор исходного сокСта */

 int new_sock; /* дСскриптор, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ accept */

 int retval; /* Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ */

 struct sockaddr_in server; /* адрСс сокСта */

 fd_set readv; /* пСрСмСнная для select */

 fd_set writev; /* пСрСмСнная для select */

 struct timeval tout; /* Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ для select */


 /* бСсконСчный Ρ†ΠΈΠΊΠ» оТидания */

 for (;;) {

  /* процСсс ΠΆΠ΄Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° Π½Π° сокСтС;

     ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΆΠ΄Π°Ρ‚ΡŒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ */

  FD_ZERO(&readv);

  FD_ZERO(&writev);

  FD_SET(sock, &readv);

  FD_SET(sock, &writev);

  tout.tv_sec = 10; /* 10 сСкунд */

  retval = select(sock+1, &readv, &writev, 0, &to);

  /* Ссли select Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π·Π½Π°Ρ‡ΠΈΡ‚ Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ */

  if (retval == 0) {

   err_ret("timeout");

   continue;

  }


  /* Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС, ΠΈΡ‰Π΅ΠΌ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ дСскриптор */

  if ( (FD_ISSET(sock, &readv)) || (FD_ISSET(sock, &writev))) {

   /* ΠΏΡ€ΠΈΠ΅ΠΌ связи с сокСта */

   new_sock = accept(sock, (struct sockaddr *)0, (int *)0);

   /* Ρ€Π°Π±ΠΎΡ‚Π° с сокСтом new_sock */

   ...

   /* Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ связи */

   close(new_sock);

  } else {

   err_ret("Π­Ρ‚ΠΎ Π½Π΅ сокСт! ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ всС дСскрипторы\n");

  }

 }

}

БистСмный Π²Ρ‹Π·ΠΎΠ² select() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ 5 Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²:

int select(int fd, fd_set *input, fd_set *output,

 fd_set *error, struct timeval *timeout);

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, fd, β€” это Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сокСтом. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚Ρ€ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π·Π°Π΄Π°ΡŽΡ‚ мноТСства Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов для оТидания условий Π²Π²ΠΎΠ΄Π° (input), Π²Ρ‹Π²ΠΎΠ΄Π° (output) ΠΈ ошибок (error). ПослСдний Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚.

ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π° Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‚Ρ€Π΅Ρ… макросов:

FD_ZERO(fd_set);

FD_SET(fd, fd_set);

FD_CLR(fd, fd_set);

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ макрос ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ мноТСство, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π²Π° макроса, соотвСтствСнно, Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ ΠΈ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор. ΠœΡ‹ использовали Π΄Π²Π° макроса для Π²Π²ΠΎΠ΄Π° ΠΈ Π΄Π²Π° для Π²Ρ‹Π²ΠΎΠ΄Π°. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ очистили мноТСство, Π° ΠΏΠΎΡ‚ΠΎΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π² Π½Π΅Π³ΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ дСскрипторы:

FD_ZERO(&readv);

FD_ZERO(&writev);

FD_SET(sock, &readv);

FD_SET(sock, &writev);

Особого Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Π° Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ послСдний ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚. Π’Π°ΠΉΠΌ-Π°ΡƒΡ‚ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ Π² сСкундах ΠΈ миллисСкундах. НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‚ Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ 2 сСкунды ΠΈ 5 миллисСкунд:

struct timeval tout; /* Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ для select */

tout.tv_sec = 2; /* 2 сСкунды */

tout.tv_usec = 5; /* 5 миллисСкунд */

Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΆΠ΄Π°Ρ‚ΡŒ бСсконСчно), ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ NULL Π² качСствС послСднСго Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°.

Ѐункция select() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ число Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ»ΠΈΡΡŒ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹Π΅ условия (Π²Π²ΠΎΠ΄/Π²Ρ‹Π²ΠΎΠ΄/ошибка) ΠΈΠ»ΠΈ -1 ΠΏΡ€ΠΈ ошибкС.

Π’ΠΎΡ‚ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select(). ΠœΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ Π²Π²ΠΎΠ΄Π° ΠΈΠ· Ρ„Π°ΠΉΠ»Π° ΠΈ ΠΈΠ· сокСта. Если Π±ΡƒΠ΄Π΅Ρ‚ достигнут Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ Π² 20 сСкунд, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ сообщСниС; Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΎΠ½ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚ сообщСниС: Β«ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ Π²Π²ΠΎΠ΄ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°/сокСта».

Листинг 27.8. Π•Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования select()

#include <unistd.h>

#include <sys/types.h>

#include <sys/time.h>

#include <sys/select.h>


int k;

int sock;

int fd;

int max_fd;

fd_set input;

struct timeval timeout;


/* инициализация Ρ„Π°ΠΉΠ»Π° ΠΈ сокСта */

...


/* Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ мноТСство Π²Π²ΠΎΠ΄Π° */

FD_ZERO(input);

FD_SET(fd, input);

FD_SET(sock, input);


max_fd = (sock > fd ? sock : fd) + 1;


/* Π—Π°Π΄Π°Π΅ΠΌ Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ */

timeout.tv_sec = 20;


k = select(max_fd, &input, NULL, NULL, &timeout);


if (k < 0)

 perror("Ошибка ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ select");

else if (k == 0) puts("TIMEOUT");

else {

 /* ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ Π²Π²ΠΎΠ΄ */

 if (FD_ISSET(fd, input))

 printf("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ Π²Π²ΠΎΠ΄ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°");

 if (FD_ISSET(sock, input))

  printf("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ Π²Π²ΠΎΠ΄ ΠΈΠ· сокСта");

}

Π’Ρ€ΠΎΠ΄Π΅ Π±Ρ‹ ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΎΡ‡Π΅Π½ΡŒ прост, Π½ΠΎ коммСнтария заслуТиваСт макрос FD_ISSET. Π‘ Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΡ‹ провСряСм, Π΅ΡΡ‚ΡŒ Π»ΠΈ Π²ΠΎ мноТСствС Π²Π²ΠΎΠ΄Π° Π²Π²ΠΎΠ΄ ΠΈΠ· ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ источника.

27.3.12. ΠΠ΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

НСкоторыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сокСтами Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π² случаС, Ссли ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ процСсс Π½Π΅ осущСствил Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ:

♦ accept();

♦ connect();

♦ read();

♦ write().

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ процСсса ΠΎΡ‡Π΅Π½ΡŒ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²ΠΎ врСмя оТидания ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π·Π°Π½ΡΡ‚ΡŒΡΡ Ρ‡Π΅ΠΌ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠΌ: Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, ΠΏΠΎΡΡ‚ΡƒΠΏΠΈΠ²ΡˆΡƒΡŽ с Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ сокСта. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ сокСты Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ систСмного Π²Ρ‹Π·ΠΎΠ²Ρ‹ ioctl().

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅:

♦ Ρ„ункция accept() сразу ΠΆΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ с ошибкой EWOULDBLOCK;

♦ Ρ„ункция connect() Ρ‚ΠΎΠΆΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π½ΠΎ с Π΄Ρ€ΡƒΠ³ΠΎΠΉ ошибкой: EINPROGRESS;

♦ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ чтСния (read(), recv(), recvfrom()) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ -1 ΠΈΠ»ΠΈ 0, Ссли Π½Π΅Ρ‚ считываСмых Π΄Π°Π½Π½Ρ‹Ρ….

ЯсноС Π΄Π΅Π»ΠΎ, Ρ‡Ρ‚ΠΎ Π² Ρ‚Π°ΠΊΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅ Π½ΡƒΠΆΠ½ΠΎ пСриодичСски ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… β€” вСдь Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ процСсс Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡ… ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ: Ссли ΠΈΡ… Π½Π΅Ρ‚, Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ просто возвратят -1 ΠΈΠ»ΠΈ 0.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ создания Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… сокСтов ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π½ΠΈΠΆΠ΅:

Листинг 27.9. ИспользованиС систСмного Π²Ρ‹Π·ΠΎΠ²Π° ioctl()

#include "sock.h"

#include <sys/ioctl.h>


void main() {

 int sock;

 int on = 1, off = 0; /* Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ дня ioctl() */

 /* Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ сокСт */