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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сСтСвых ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 217

Автор Уильям БтивСнс

Π’ листингС 28.24 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° пСрвая Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main.

Листинг 28.24. ΠŸΠ΅Ρ€Π²Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main: созданиС сокСтов

//icmpd/icmpd.c

 1 #include "icmpd.h"


 2 int

 3 main(int argc, char **argv)

 4 {

 5  int i, sockfd;

 6  struct sockaddr_un sun;


 7  if (argc != 1)

 8   err_quit("usage: icmpd");


 9  maxi = -1; /* индСкс массива client[] */

10  for (i = 0; i < FD_SETSIZE; i++)

11   client[i].connfd = -1; /* -1 ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ свободный элСмСнт */

12  FD_ZERO(&allset);


13  fd4 = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

14  FD_SET(fd4, &allset);

15  maxfd = fd4;


16 #ifdef IPV6

17  fd6 = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);

18  FD_SET(fd6, &allset);

19  maxfd = max(maxfd, fd6);

20 #endif


21  listenfd = Socket(AF_UNIX, SOCK_STREAM, 0);

22  sun.sun_family = AF_LOCAL;

23  strcpy(sun.sun_path, ICMPD_PATH);

24  unlink(ICMPD_PATH);

25  Bind(listenfd, (SA*)&sun, sizeof(sun));

26  Listen(listenfd, LISTENQ);

27  FD_SET(listenfd, &allset);

28  maxfd = max(maxfd, listenfd);

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ массива client

9-10 Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ся массив client ΠΏΡƒΡ‚Π΅ΠΌ присваивания значСния -1 элСмСнту присоСдинСнного сокСта.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сокСтов

12-28 Π‘ΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Ρ‚Ρ€ΠΈ сокСта: ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ICMPv4, ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ICMPv6 ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix. ΠœΡ‹ связываСм ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bind своС Π·Π°Ρ€Π°Π½Π΅Π΅ извСстноС ΠΏΠΎΠ»Π½ΠΎΠ΅ имя с сокСтом ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ listen. Π­Ρ‚ΠΎ сокСт, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect. Для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select Ρ‚Π°ΠΊΠΆΠ΅ вычисляСтся ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ дСскриптор, Π° для Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept Π² памяти размСщаСтся структура адрСса сокСта.

Π’ листингС 28.25 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° вторая Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main. Она содСрТит бСсконСчный Ρ†ΠΈΠΊΠ», Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ, ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ² ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΈΠ· дСскрипторов Π΄Π΅ΠΌΠΎΠ½Π°.

Листинг 28.25. Вторая Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main: ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ³ΠΎ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ дСскриптора

//icmpd/icmpd.c

29  for (;;) {

30   rset = allset;

31   nready = Select(maxfd+1, &rset, NULL, NULL, NULL);


32   if (FD_ISSET(listenfd, &rset))

33    if (readable_listen() <= 0)

34     continue;


35   if (FD_ISSET(fd4, &rset))

36    if (readable_v4() <= 0)

37     continue;


38 #ifdef IPV6

39   if (FD_ISSET(fd6, &rset))

40    if (readable_v6() <= 0)

41     continue;

42 #endif


43   for (i = 0; i <= maxi; i++) { /* ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° всСх ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² */

44    if ( (sockfd = client[i].connfd) < 0)

45     continue;

46    if (FD_ISSET(sockfd, &rset))

47     if (readable_conn(i) <= 0)

48      break; /* Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… дСскрипторов большС Π½Π΅Ρ‚ */

49   }

50  }

51  exit(0);

52 }

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ Π΄ΠΎΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ сокСта Unix

32-34 ΠŸΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix провСряСтся Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΈ Ссли ΠΎΠ½ Π³ΠΎΡ‚ΠΎΠ², запускаСтся функция readable_listen. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ nready β€” количСство дСскрипторов, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ функция select Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠ°ΠΊ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ β€” являСтся глобальной. КаТдая ΠΈΠ· Π½Π°ΡˆΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ readablΠ΅_XXX ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° 1, ΠΈ Π½ΠΎΠ²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ являСтся Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Когда Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ достигаСт нуля, это Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ всС Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ дСскрипторы ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Ρ‹, ΠΈ поэтому функция select вызываСтся снова.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сокСтов ICMP

35-42 ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅Ρ‚ся ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ICMPv4, Π° Π·Π°Ρ‚Π΅ΠΌ ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ сокСт ICMPv6.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° присоСдинСнных Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹Ρ… сокСтов Unix

43-49 Π—Π°Ρ‚Π΅ΠΌ провСряСтся, Π³ΠΎΡ‚ΠΎΠ² Π»ΠΈ для чтСния ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΈΠ· присоСдинСнных Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹Ρ… сокСтов Unix. Π“ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ для чтСния ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… сокСтов ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отослал дСскриптор ΠΈΠ»ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ.

Π’ листингС 28.26 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° функция readable_listen, вызываСмая, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ сокСт Π³ΠΎΡ‚ΠΎΠ² для чтСния. Π­Ρ‚ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π½ΠΎΠ²ΠΎΠ΅ клиСнтскоС соСдинСниС.

Листинг 28.26. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½ΠΎΠ²ΠΎΠ³ΠΎ соСдинСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//icmpd/readablΠ΅_listen.c

 1 #include "icmpd.h"


 2 int

 3 readable_listen(void)

 4 {

 5  int i, connfd;

 6  socklen_t clilen;


 7  clilen = sizeof(cliaddr);

 8  connfd = Accept(listenfd, (SA*)&cliaddr, &clilen);

 9  /* поиск ΠΏΠ΅Ρ€Π²ΠΎΠΉ свободной структуры Π² массивС client[] */

10  for (i = 0; i < FD_SETSIZE; i++)

11   if (client[i].connfd < 0) {

12    client[i].connfd = connfd; /* сохранСниС дСскриптора */

13    break;

14   }

15  if (i == FD_SETSIZE) {

16   close(connfd); /* Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ */

17   return(--nready); /* Π³Ρ€ΡƒΠ±ΠΎΠ΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ соСдинСния */

18  }

19  printf("new connection, i = %d, connfd = %d\n", i, connfd);


20  FD_SET(connfd, &allset); /* Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ дСскриптора Π² Π½Π°Π±ΠΎΡ€ */

21  if (connfd > maxfd)

22   maxfd = connfd; /* для select() */

23  if (i > maxi)

24   maxi = i; /* ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ индСкс Π² массивС client[] */


25  return(--nready);

26 }

7-25 ΠŸΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ся соСдинСниС ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ свободный элСмСнт массива client. Код Π΄Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ скопирован ΠΈΠ· Π½Π°Ρ‡Π°Π»Π° ΠΊΠΎΠ΄Π°, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π² листингС 6.4. Если свободных элСмСнтов Π² массивС Π½Π΅Ρ‚, ΠΌΡ‹ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС ΠΈ занимаСмся обслуТиваниСм ΡƒΠΆΠ΅ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ².

Когда присоСдинСнный сокСт Π³ΠΎΡ‚ΠΎΠ² для чтСния, вызываСтся функция readablΠ΅_conn (листинг 28.27), Π° Π΅Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ являСтся индСкс Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π² массивС client.

Листинг 28.27. Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, дСскриптора ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//icmpd/readable_conn.c

 1 #include "icmpd.h"


 2 int

 3 readable_conn(int I)

 4 {

 5  int unixfd, recvfd;

 6  char c;

 7  ssize_t n;

 8  socklen_t len;

 9  struct sockaddr_storage ss;


10  unixfd = client[i].connfd;

11  recvfd = -1;

12  if ((n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) {

13   err_msg("client %d terminated, recvfd = %d", i, recvfd);

14   goto clientdone; /* вСроятно, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ */

15  }


16  /* Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ, дСскриптор */

17  if (recvfd < 0) {

18   err_msg("read_fd did not return descriptor");

19   goto clienterr;

20  }

Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, дСскриптора

13-18 Π’Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ read_fd, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΡƒΡŽ Π² листингС 15.9, для считывания Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, дСскриптора. Если Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π» свою Ρ‡Π°ΡΡ‚ΡŒ соСдинСния, вСроятно, Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ² своС Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

ΠŸΡ€ΠΈ написании ΠΊΠΎΠ΄Π° ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π²Ρ‹Π±ΠΈΡ€Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для связи ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΠΈ Π΄Π΅ΠΌΠΎΠ½ΠΎΠΌ β€” Π»ΠΈΠ±ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix, Π»ΠΈΠ±ΠΎ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix. ДСскриптор сокСта UDP ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ Ρ‡Π΅Ρ€Π΅Π· любой Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix. ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚Π΅Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚Π΄Π°Π½ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΌΡƒ сокСту, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ позволяСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ВсС дСскрипторы автоматичСски Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π² Ρ‚ΠΎΠΌ числС ΠΈ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ для связи с Π΄Π΅ΠΌΠΎΠ½ΠΎΠΌ, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ‡Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ удаляСтся Π΄Π΅ΠΌΠΎΠ½ΠΎΠΌ ΠΈΠ· массива client. Если Π±Ρ‹ ΠΌΡ‹ использовали сокСт Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ, Ρ‚ΠΎ Π½Π΅ ΡƒΠ·Π½Π°Π»ΠΈ Π±Ρ‹, ΠΊΠΎΠ³Π΄Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ.

16-20 Π•сли ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π·Π°ΠΊΡ€Ρ‹Π» соСдинСниС, ΠΆΠ΄Π΅ΠΌ получСния дСскриптора. Вторая Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ readable_conn ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 28.28.

Листинг 28.28. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½ΠΎΠΌΠ΅Ρ€Π° ΠΏΠΎΡ€Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ связал с UDP-сокСтом

//icmpd/readable_conn.c

21  len = sizeof(ss);

22  if (getsockname(recvfd, (SA*)&ss, &len) < 0) {

23   err_ret("getsockname error");

24   goto clienterr;

25  }


26  client[i].family = ss.ss_family;

27  if ((client[i].lport = sock_get_port((SA*)&ss, len)) == 0) {

28   client[i].lport = sock_bind_wild(recvfd, client[i].family);

29   if (client[i].lport <= 0) {

30    err_ret("error binding ephemeral port");

31    goto clienterr;

32   }

33  }

34  Write(unixfd, "1", 1); /* сообщСниС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΎΠ± успСхС */

35  Close(recvfd); /* Ρ€Π°Π±ΠΎΡ‚Π° с UDP-сокСтом ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° */

36  return(--nready);


37 clienterr:

38  Write(unixfd, "0", 1); /* сообщСниС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΎΠ± ошибкС */

39 clientdone:

40  Close(unixfd);

41  if (recvfd >= 0)

42   Close(recvfd);

43  FD_CLR(unixfd, &allset);

44  client[i].connfd = -1;

45  return(--nready);

46 }

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½ΠΎΠΌΠ΅Ρ€Π° ΠΏΠΎΡ€Ρ‚Π°, связанного с сокСтом UDP

21-25 Π’ызываСтся функция getsockname, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π΄Π΅ΠΌΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π°, связанного с сокСтом. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ нСизвСстно, ΠΊΠ°ΠΊΠΎΠ² Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π°, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ для размСщСния структуры адрСса сокСта, ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ структуру sockaddr_storage, которая достаточно Π²Π΅Π»ΠΈΠΊΠ° для структуры адрСса сокСта любого ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ систСмой Ρ‚ΠΈΠΏΠ° ΠΈ обСспСчиваСт Π½ΡƒΠΆΠ½ΠΎΠ΅ Π²Ρ‹Ρ€Π°Π²Π½ΠΈΠ²Π°Π½ΠΈΠ΅.