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

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

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

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚: нСпустой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ выполнСния, NULL Π² случаС ошибки

Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° port Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ записано Π² сСтСвом порядкС Π±Π°ΠΉΡ‚ΠΎΠ². Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π° этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ Π½ΠΈΠΆΠ΅:

struct servent *sptr;


sptr = getservbyport(htons(53), "udp"); /* DNS с использованиСм UDP */

sptr = getservbyport(htons(21), "tcp"); /* FTP с использованиСм TCP */

sptr = getservbyport(htons(21), NULL);  /* FTP с использованиСм TCP */

sptr = getservbyport(htons(21), "udp"); /* этот Π²Ρ‹Π·ΠΎΠ² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ошибкС */

ПослСдний Π²Ρ‹Π·ΠΎΠ² оказываСтся Π½Π΅ΡƒΠ΄Π°Ρ‡Π½Ρ‹ΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π΅Ρ‚ слуТбы, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΉ ΠΏΠΎΡ€Ρ‚ 21 с ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ UDP.

ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΠΎΠΌΠ΅Ρ€Π° ΠΏΠΎΡ€Ρ‚ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ с TCP для ΠΎΠ΄Π½ΠΎΠΉ слуТбы, Π° с UDP β€” для ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

freebsd % grep 514 /etc/services

shell  514/tcp cmd #like exec, but automatic

syslog 514/udp

Π—Π΄Π΅ΡΡŒ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ€Ρ‚ 514 ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ rsh с TCP ΠΈ Π΄Π΅ΠΌΠΎΠ½ΠΎΠΌ syslog с UDP. Π­Ρ‚ΠΎ Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½ΠΎ для ΠΏΠΎΡ€Ρ‚ΠΎΠ² 512-514.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ gethostbyname ΠΈ getservbyname

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ нашСго TCP-ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ Π΄Π°Ρ‚Ρ‹, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π² листингС 1.1, Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ gethostbyname ΠΈ getservbyname ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки: имя ΡƒΠ·Π»Π° ΠΈ имя слуТбы. Наша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 11.2. Π­Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ‚Π°ΠΊΠΆΠ΅ дСмонстрируСт ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ установлСнии соСдинСния со всСми IP-адрСсами сСрвСра Π½Π° ΡƒΠ·Π»Π΅, ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΌ нСсколько сСтСвых интСрфСйсов: ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽΡ‚ΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° соСдинСниС Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ установлСно ΠΈΠ»ΠΈ ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π±Ρ€Π°Π½Ρ‹ всС адрСса.

Листинг 11.2. Наш ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ Π΄Π°Ρ‚Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ gethostbyname ΠΈ getservbyname

//names/daytimetcpcli1.c

 1 #include "unp.h"


 2 int

 3 main(int argc, char **argv)

 4 {

 5  int sockfd, n;

 6  char recvline[MAXLINE + 1];

 7  struct sockaddr_in servaddr;

 8  struct in_addr **pptr;

 9  struct in_addr *inetaddrp[2];

10  struct in_addr inetaddr;

11  struct hostent *hp;

12  struct servent *sp;


13  if (argc != 3)

14   err_quit("usage: daytimetcpcli1 <hostname> <service>");


15  if ((hp = gethostbyname(argv[1])) == NULL) {

16   if (inet_aton(argv[1], &inetaddr) == 0) {

17    err_quit("hostname error for %s: %s", argv[1],

18    hstrerror(h_errno));

19   } else {

20    inetaddrp[0] = &inetaddr;

21    inetaddrp[1] = NULL;

22    pptr = inetaddrp;

23   }

24  } else {

25   pptr = (struct in_addr**)hp->h_addr_list;

26  }


27  if ((sp = getservbyname(argv[2], "tcp")) == NULL)

28   err_quit("getservbyname error for %s", argv[2]);


29  for (; *pptr != NULL; pptr++) {

30   sockfd = Socket(AF_INET, SOCK_STREAM, 0);


31   bzero(&servaddr, sizeof(servaddr));

32   servaddr.sin_family = AF_INET;

33   servaddr.sin_port = sp->s_port;

34   memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));

35   printf("trying %s\n", Sock_ntop((SA*)&servaddr, sizeof(servaddr)));


36   if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) == 0)

37    break; /* ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ */

38   err_ret("connect error");

39   close(sockfd);

40  }

41  if (*pptr == NULL)

42   err_quit("unable to connect");


43  while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {

44   recvline[n] = 0; /* null terminate */

45   Fputs(recvline, stdout);

46  }

47  exit(0);

48 }

Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ gethostbyname ΠΈ getservbyname

13-28 ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки β€” это имя ΡƒΠ·Π»Π°, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ΅ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ gethostbyname, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” имя слуТбы, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ΅ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getservbyname. Наш ΠΊΠΎΠ΄ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ использованиС ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° TCP, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getservbyname. Если Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ gethostbyname Π½Π΅ удаСтся Π½Π°ΠΉΡ‚ΠΈ Π½ΡƒΠΆΠ½ΠΎΠ΅ имя, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ inet_aton (см. Ρ€Π°Π·Π΄Π΅Π» 3.6), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π½Π΅ являСтся Π»ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки IP-адрСсом Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ASCII. Π’ этом случаС формируСтся список ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ элСмСнта β€” этого IP-адрСса.

ΠŸΠ΅Ρ€Π΅Π±ΠΎΡ€ всСх адрСсов

29-35 Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ пишСм Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ socket ΠΈ connect Π² Ρ†ΠΈΠΊΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСтся для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ адрСса сСрвСра, ΠΏΠΎΠΊΠ° ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect Π½Π΅ окаТСтся ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ ΠΈΠ»ΠΈ ΠΏΠΎΠΊΠ° Π½Π΅ закончится список сСрвСров. ПослС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ socket ΠΌΡ‹ заполняСм структуру адрСса сокСта Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π° IP-адрСсом ΠΈ Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ ΠΏΠΎΡ€Ρ‚Π° сСрвСра. Π₯отя Π² цСлях увСличСния ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ вынСсти ΠΈΠ· Ρ†ΠΈΠΊΠ»Π° Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bzero ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π²Π° присваивания, наш ΠΊΠΎΠ΄ Π»Π΅Π³Ρ‡Π΅ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π² Ρ‚Π°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅, ΠΊΠ°ΠΊ ΠΎΠ½ прСдставлСн сСйчас. УстановлСниС соСдинСния с сСрвСром Ρ€Π΅Π΄ΠΊΠΎ являСтся основным источником ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ сСтСвого ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect

36-39 Π’ызываСтся функция connect, ΠΈ Ссли Π²Ρ‹Π·ΠΎΠ² оказываСтся ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΌ, функция break Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ†ΠΈΠΊΠ». Если ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСниС Π½Π΅ удаСтся, ΠΌΡ‹ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ сообщСниС ΠΎΠ± ошибкС ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ сокСт. ВспомнитС, Ρ‡Ρ‚ΠΎ дСскриптор, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect оказался Π½Π΅ΡƒΠ΄Π°Ρ‡Π½Ρ‹ΠΌ, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ большС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Ρ‚.

Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

41-42 Π•сли Ρ†ΠΈΠΊΠ» Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect Π½Π΅ закончился успСхом, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ.

Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΎΡ‚Π²Π΅Ρ‚Π° сСрвСра

43-47 ΠœΡ‹ считываСм ΠΎΡ‚Π²Π΅Ρ‚ сСрвСра ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΊΠΎΠ³Π΄Π° сСрвСр Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ соСдинСниС.

Если ΠΌΡ‹ запустим эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΡƒΠΊΠ°Π·Π°Π² ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½Π°ΡˆΠΈΡ… ΡƒΠ·Π»ΠΎΠ², Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ сСрвСр Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ Π΄Π°Ρ‚Ρ‹, ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

freebsd % daytimetcpcli1 aix daytime

trying 192.168.42.2:13

Sun Jul 27 22:44:19 2003

Но Π΅Ρ‰Π΅ интСрСснСС Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΠ²ΡˆΠΈΡΡŒ ΠΊ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ с нСсколькими сСтСвыми интСрфСйсами, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ сСрвСр Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ Π΄Π°Ρ‚Ρ‹:

solaris % daytimetcpcli1 gateway.tuc.noao.edu daytime

trying 140.252.108.1:13

connect error: Operation timed out

trying 140.252.1.4:13

connect error: Operation timed out

trying 140.252.104.1:13

connect error: Connection refused

unable to connect

11.6. Ѐункция getaddrinfo

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ gethostbyname ΠΈ gethostbyaddr ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ IPv4. Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ IPv6 разрабатывался Π² нСсколько этапов (история Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ описана Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 11.20), ΠΈ Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»Π°ΡΡŒ функция getaddrinfo. ПослСдняя осущСствляСт Ρ‚Ρ€Π°Π½ΡΠ»ΡΡ†ΠΈΡŽ ΠΈΠΌΠ΅Π½ Π² адрСса ΠΈ слуТб Π² ΠΏΠΎΡ€Ρ‚Ρ‹, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ½Π° список структур sockaddr, Π° Π½Π΅ список адрСсов. Π’Π°ΠΊΠΈΠ΅ структуры ΠΌΠΎΠ³ΡƒΡ‚ нСпосрСдствСнно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ функциями сокСтов. Благодаря этому функция getaddrinfo скрываСт всС различия ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°ΠΌΠΈ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ со структурами адрСсов сокСтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ getaddrinfo. Π­Ρ‚Π° функция опрСдСляСтся стандартом POSIX.

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

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² POSIX происходит ΠΎΡ‚ Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½Π΅Π³ΠΎ прСдлоТСния ΠšΠ΅ΠΉΡ‚Π° Бклоуэра (Keith Sklower) для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ getconninfo. Π­Ρ‚Π° функция стала Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ обсуТдСний с Π­Ρ€ΠΈΠΊΠΎΠΌ ОлмСном (Eric Allman), Π’ΠΈΠ»Π»ΡŒΡΠΌΠΎΠΌ Дастом (William Durst), Майклом ΠšΠ°Ρ€Π΅Π»ΡΠΎΠΌ (Michael Karels) ΠΈ Π‘Ρ‚ΠΈΠ²Π΅Π½ΠΎΠΌ Вайсом (Steven Wise), Π° Ρ‚Π°ΠΊΠΆΠ΅ Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½Π΅ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, написанной Π­Ρ€ΠΈΠΊΠΎΠΌ ОлмСном. Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ указания ΠΈΠΌΠ΅Π½ΠΈ ΡƒΠ·Π»Π° ΠΈ ΠΈΠΌΠ΅Π½ΠΈ слуТбы достаточно для соСдинСния с этой слуТбой нСзависимо ΠΎΡ‚ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, Π±Ρ‹Π»ΠΎ сдСлано ΠœΠ°Ρ€ΡˆΠ°Π»ΠΎΠΌ Π ΠΎΡƒΠ·ΠΎΠΌ (Marshall Rose) Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ X/Open.

#include <netdb.h>


int getaddrinfo(const char *hostname, const char *service,

 const struct addrinfo *hints, struct addrinfo **result);

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚: 0 Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ выполнСния, Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² случаС ошибки

(см. Ρ‚Π°Π±Π». 11.2).

Π§Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ result функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° связный список структур addrinfo, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ задаСтся Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ <netdb.h>:

struct addrinfo {

 int    ai_flags;          /* AI_PASSIVE, AI_CANONNAME */

 int    ai_family;         /* AF_xxx */

 int    ai_socktype;       /* SOCK_xxx */

 int    ai_protocol;       /* 0 ΠΈΠ»ΠΈ IPPROTO_xxx для IPv4 ΠΈ IPv6 */

 size_t ai_addrlen;        /* Π΄Π»ΠΈΠ½Π° ai_addr */

 char*  ai_canonname;      /* ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° каноничСскоС имя ΡƒΠ·Π»Π° */

 struct sockaddr *ai_addr; /* ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру адрСса сокСта */

 struct addrinfo *ai_next; /* ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ структуру Π² связном

                              спискС */

};

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ hostname β€” это Π»ΠΈΠ±ΠΎ имя ΡƒΠ·Π»Π°, Π»ΠΈΠ±ΠΎ строка адрСса (Ρ‚ΠΎΡ‡Π΅Ρ‡Π½ΠΎ-дСсятичная запись для IPv4 ΠΈΠ»ΠΈ ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚Π΅Ρ€ΠΈΡ‡Π½Π°Ρ строка для IPv6). ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ service β€” это Π»ΠΈΠ±ΠΎ имя слуТбы, Π»ΠΈΠ±ΠΎ строка, содСрТащая дСсятичный Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π°. (Π‘ΠΌ. Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 11.4.)

АргумСнт hints β€” это Π»ΠΈΠ±ΠΎ пустой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, Π»ΠΈΠ±ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру addrinfo, Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΡƒΡŽ рСкомСндациями Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ процСсса ΠΎ Ρ‚ΠΈΠΏΠ°Ρ… ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΎΠ½ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ. НапримСр, Ссли заданная слуТба прСдоставляСтся ΠΈ для TCP, ΠΈ для UDP (слуТба domain, которая ссылаСтся Π½Π° сСрвСр DNS), Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ процСсс ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ элСмСнту ai_socktype структуры hints Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ SOCK_DGRAM. Π’ΠΎΠ³Π΄Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ мСсто Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ½Ρ‹Ρ… сокСтов.