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

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

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

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

Π’ листингС 21.8 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция main нашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Листинг 21.8. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сокСтов, Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fork ΠΈ запуск отправитСля ΠΈ получатСля

//mcast/main.c

 1 #include "unp.h"


 2 void recv_all(int, socklen_t);

 3 void send_all(int. SA *, socklen_t);


 4 int

 5 main(int argc, char **argv)

 6 {

 7  int sendfd, recvfd;

 8  const int on = 1;

 9  socklen_t salen;

10  struct sockaddr *sasend, *sarecv;


11  if (argc != 3)

12   err_quit("usage: sendrecv <IP-multicast-address> <port#>");


13  sendfd = Udp_client(argv[1], argv[2], (void**)&sasend, &salen);


14  recvfd = Socket(sasend->sa_family, SOCK_DGRAM, 0);


15  Setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));


16  sarecv = Malloc(salen);

17  memcpy(sarecv, sasend, salen);

18  Bind(recvfd, sarecv, salen);


19  Mcast_join(recvfd, sasend, salen, NULL, 0);

20  Mcast_set_loop(sendfd, 0);


21  if (Fork() == 0)

22   recv_all(recvfd, salen); /* Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс -> ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ */


23  send_all(sendfd, sasend, salen); /* Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ -> ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° */

24 }

ΠœΡ‹ создаСм Π΄Π²Π° сокСта, ΠΎΠ΄ΠΈΠ½ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΈ ΠΎΠ΄ΠΈΠ½ для получСния. Нам Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ сокСт связался ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bind с Π³Ρ€ΡƒΠΏΠΏΠΎΠΉ ΠΈ ΠΏΠΎΡ€Ρ‚ΠΎΠΌ, допустим 239.255.1.2, ΠΏΠΎΡ€Ρ‚ 8888. (ВспомнитС, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ просто ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ IP-адрСс ΠΈ ΠΏΠΎΡ€Ρ‚ 8888, Π½ΠΎ связываниС с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ адрСсом многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сокСтом Π΄Ρ€ΡƒΠ³ΠΈΡ… Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΈΠΉΡ‚ΠΈ Π½Π° ΠΏΠΎΡ€Ρ‚ получатСля 8888.) Π”Π°Π»Π΅Π΅, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ сокСт присоСдинился ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅. ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ сокСт Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° этот ΠΆΠ΅ адрСс многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈ этот ΠΆΠ΅ ΠΏΠΎΡ€Ρ‚, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½Π° 239.255.1.2, ΠΏΠΎΡ€Ρ‚ 8888. Но Ссли ΠΌΡ‹ попытаСмся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ сокСт ΠΈ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ, ΠΈ для получСния, Ρ‚ΠΎ адрСсом отправитСля для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bind Π±ΡƒΠ΄Π΅Ρ‚ 239.255.1.2.8888 (здСсь ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ нотация netstat), Π° адрСсом получатСля для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sendto β€” Ρ‚Π°ΠΊΠΆΠ΅ 239.255.1.2.8888. Но адрСс отправитСля, связанный с сокСтом, становится IP-адрСсом отправитСля Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ UDP, a RFC 1122 [10] Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ΅ IP ΠΈΠΌΠ΅Ρ‚ΡŒ IP-адрСс отправитСля, ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ адрСсом многоадрСсной ΠΈΠ»ΠΈ ΡˆΠΈΡ€ΠΎΠΊΠΎΠ²Π΅Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ. (Π‘ΠΌ. Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 21.2.) Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΌΡ‹ создаСм Π΄Π²Π° сокСта: ΠΎΠ΄ΠΈΠ½ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ, Π΄Ρ€ΡƒΠ³ΠΎΠΉ для получСния.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅Π³ΠΎ сокСта

13 ΠΠ°ΡˆΠ° функция udp_client создаСт ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ сокСт, обрабатывая Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Π΄Π°ΡŽΡ‚ адрСс многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π°. Π­Ρ‚Π° функция Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ структуру адрСса сокСта, Π³ΠΎΡ‚ΠΎΠ²ΡƒΡŽ ΠΊ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sendto, ΠΈ Π΄Π»ΠΈΠ½Ρƒ этой структуры.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅Π³ΠΎ сокСта ΠΈ связываниС (ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bind) с адрСсом многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈ ΠΏΠΎΡ€Ρ‚ΠΎΠΌ

14-18 ΠœΡ‹ создаСм ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ сокСт, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚ΠΎ ΠΆΠ΅ сСмСйство адрСсов, Ρ‡Ρ‚ΠΎ ΠΈ ΠΏΡ€ΠΈ создании ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅Π³ΠΎ сокСта, ΠΈ устанавливаСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ сокСта SO_REUSEADDR, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ мноТСству экзСмпляров этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ Π½Π° ΡƒΠ·Π»Π΅. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ выдСляСм Π² памяти пространство для структуры адрСса этого сокСта, ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π΅Π΅ содСрТимоС ΠΈΠ· структуры адрСса ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅Π³ΠΎ сокСта (адрСс ΠΈ ΠΏΠΎΡ€Ρ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ взяты ΠΈΠ· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки) ΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ bind связываСм адрСс многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈ ΠΏΠΎΡ€Ρ‚ с ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΌ сокСтом.

ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅ ΠΈ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π·Π°ΠΊΠΎΠ»ΡŒΡ†ΠΎΠ²ΠΊΠΈ

19-20 ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Π½Π°ΡˆΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ mcast_join, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅ Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰Π΅ΠΌ сокСтС, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π½Π°ΡˆΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ mcast_set_loop, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π·Π°ΠΊΠΎΠ»ΡŒΡ†ΠΎΠ²ΠΊΡƒ Π½Π° ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅ΠΌ сокСтС. Для присоСдинСния Π·Π°Π΄Π°Π΅ΠΌ имя интСрфСйса Π² Π²ΠΈΠ΄Π΅ пустого указатСля ΠΈ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ индСкс интСрфСйса, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ядру Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ интСрфСйс ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ.

Ѐункция fork ΠΈ Π²Ρ‹Π·ΠΎΠ² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ

21-23 ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fork, послС Ρ‡Π΅Π³ΠΎ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ процСссом становится ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠΉ Ρ†ΠΈΠΊΠ», Π° Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ β€” ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ.

Наша функция sendmail, ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π°Ρ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ΅ многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 с, ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 21.9. Ѐункция main ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² дСскриптор сокСта, ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру адрСса сокСта, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ адрСс получатСля многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈ ΠΏΠΎΡ€Ρ‚, ΠΈ Π΄Π»ΠΈΠ½Ρƒ структуры.

Листинг 21.9. ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹ многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 с

//mcast/send.c

 1 #include "unp.h"

 2 #include <sys/utsname.h>


 3 #define SENDRATE 5 /* ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 с */


 4 void

 5 send_all(int sendfd, SA *sadest, socklen_t salen)

 6 {

 7  static char line[MAXLINE]; /* имя ΡƒΠ·Π»Π° ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса */

 8  struct utsname myname;


 9  if (uname(&myname) < 0)

10   err_sys("uname error");

11  snprintf(line, sizeof(line), "%s, %d\n", myname, nodename, getpid());


12  for (;;) {

13   Sendto(sendfd, line, strlen(line), 0, sadest, salen);

14   sleep(SENDRATE);

15  }

16 }

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π½ΠΈ ΡƒΠ·Π»Π° ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ содСрТимого Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹

9-11 ΠœΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя ΡƒΠ·Π»Π° ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ uname ΠΈ создаСм строку Π²Ρ‹Π²ΠΎΠ΄Π°, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ это имя ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса.

ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π² Ρ€Π΅ΠΆΠΈΠΌ оТидания

12-15 ΠœΡ‹ отправляСм Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡƒ ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sleep ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² состояниС оТидания Π½Π° 5 с.

Ѐункция recv_all, содСрТащая бСсконСчный Ρ†ΠΈΠΊΠ» получСния, ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 21.10.

Листинг 21.10. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ всСх Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ для Π³Ρ€ΡƒΠΏΠΏΡ‹, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΠ»ΠΈΡΡŒ

//mcast/recv.c

 1 #include "unp.h"


 2 void

 3 recv_all(int recvfd, socklen_t salen)

 4 {

 5  int n;

 6  char line[MAXLINE + 1];

 7  socklen_t len;

 8  struct sockaddr *safrom;


 9  safrom = Malloc(salen);


10  for (;;) {

11   len = salen;

12   n = Recvfrom(recvfd, line, MAXLINE, 0, safrom, &len);


13   line[n] = 0; /* Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ Π½ΡƒΠ»ΡŒ */

14   printf("from %s: %s", Sock_ntop(safrom, len), line);

15  }

16 }

Π Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π² памяти структуры адрСса сокСта

9 ΠŸΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ recvfrom Π² памяти выдСляСтся пространство для структуры адрСса сокСта, Π² ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ записываСтся адрСс отправитСля.

Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ

10-15 ΠšΠ°ΠΆΠ΄Π°Ρ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ° считываСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ recvfrom, дополняСтся символом ΠΊΠΎΠ½Ρ†Π° строки (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½ΡƒΠ»Π΅ΠΌ) ΠΈ выводится.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€

ΠœΡ‹ запускаСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π² Π΄Π²ΡƒΡ… систСмах: freebsd4 ΠΈ macosx. КаТдая систСма Π²ΠΈΠ΄ΠΈΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹, отправляСмыС Π΄Ρ€ΡƒΠ³ΠΎΠΉ.

freebsd4 % sendrecv 239.255.1.2 8888

from 172.24.37.78:51297: macosx, 21891

from 172.24.37.78:51297: macosx, 21891

from 172.24.37.78:51297: macosx, 21891

from 172.24.37.78:51297: macosx, 21891


macosx % sendrecv 239.255.1.2 8888

from 172.24.37.94.1215: freebsd4, 55372

from 172.24.37.94.1215: freebsd4, 55372

from 172.24.37.94.1215: freebsd4, 55372

from 172.24.37.94.1215: freebsd4, 55372

21.11. SNTP: простой ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ сСтСвой ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»

Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ сСтСвой ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» (Network Time Protocol, NTP) β€” это слоТный ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» синхронизации часов Π² глобальной ΠΈΠ»ΠΈ локальной сСти. Π•Π³ΠΎ Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ часто ΠΌΠΎΠΆΠ΅Ρ‚ Π΄ΠΎΡΡ‚ΠΈΠ³Π°Ρ‚ΡŒ миллисСкунд. Π’ RFC 1305 [76] этот ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описан, Π° Π² RFC 2030 [77] рассматриваСтся ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» SNTP β€” упрощСнная вСрсия NTP, прСдназначСнная для ΡƒΠ·Π»ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π½Π΅ трСбуСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ NTP. Π’ΠΈΠΏΠΈΡ‡Π½ΠΎΠΉ являСтся ситуация, ΠΊΠΎΠ³Π΄Π° нСсколько ΡƒΠ·Π»ΠΎΠ² Π² локальной сСти ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ свои часы Ρ‡Π΅Ρ€Π΅Π· Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΡƒΠ·Π»Π°ΠΌΠΈ NTP, Π° Π·Π°Ρ‚Π΅ΠΌ Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡŽΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² локальной сСти с использованиСм Π»ΠΈΠ±ΠΎ ΡˆΠΈΡ€ΠΎΠΊΠΎΠ²Π΅Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ, Π»ΠΈΠ±ΠΎ многоадрСсной ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ.

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ создадим ΠΊΠ»ΠΈΠ΅Π½Ρ‚ SNTP, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅Ρ‚ ΡˆΠΈΡ€ΠΎΠΊΠΎΠ²Π΅Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΈΠ»ΠΈ Π³Ρ€ΡƒΠΏΠΏΠΎΠ²Ρ‹Π΅ сообщСния NTP Π½Π° всСх присоСдинСнных сСтях, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Ρ€Π°Π·Π½ΠΈΡ†Ρƒ Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠΌ NTP ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ истинным Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΡƒΠ·Π»Π°. ΠœΡ‹ Π½Π΅ пытаСмся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ это врСмя, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ для этого Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ ΠΏΡ€Π°Π²Π° ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.