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

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

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

delta = measuredRTT - srtt

srtt ← srtt + g Γ— delta

rttvar ← rttvar + h (|delta| - rttvar)

RTO = srtt + 4 Γ— rttvar

delta β€” это Ρ€Π°Π·Π½ΠΎΡΡ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½Π½Ρ‹ΠΌ RTT ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ сглаТСнным ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ RTT (srtt). g β€” это ΠΏΡ€ΠΈΡ€Π°Ρ‰Π΅Π½ΠΈΠ΅, примСняСмоС ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ RTT, Ρ€Π°Π²Π½ΠΎΠ΅ 1/8. h β€” это ΠΏΡ€ΠΈΡ€Π°Ρ‰Π΅Π½ΠΈΠ΅, примСняСмоС ΠΊ сглаТСнному ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ срСднСго отклонСния, Ρ€Π°Π²Π½ΠΎΠ΅ ΒΌ.

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

Π”Π²Π° приращСния ΠΈ ΠΌΠ½ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒ 4 Π² вычислСнии RTO ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½Ρ‹ стСпСнями числа 2 ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ вычислСны с использованиСм ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ сдвига вмСсто дСлСния ΠΈ умноТСния. На самом Π΄Π΅Π»Π΅ рСализация TCP Π² ядрС (см. Ρ€Π°Π·Π΄Π΅Π» 25.7 [128]) для ускорСния вычислСний ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π°Ρ€ΠΈΡ„ΠΌΠ΅Ρ‚ΠΈΠΊΡƒ с фиксированной Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ, Π½ΠΎ ΠΌΡ‹ для простоты ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π² нашСм ΠΊΠΎΠ΄Π΅ вычислСния с ΠΏΠ»Π°Π²Π°ΡŽΡ‰Π΅ΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ.

Π”Ρ€ΡƒΠ³ΠΎΠΉ Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹ΠΉ Π² [52], Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ истСчСнии Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ для ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ RTO Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΡΠΊΡΠΏΠΎΠ½Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ смСщСниС (exponential backoff). НапримСр, Ссли нашС ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTO Ρ€Π°Π²Π½ΠΎ 2 с ΠΈ Π·Π° это врСмя ΠΎΡ‚Π²Π΅Ρ‚Π° Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTO Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΠΎ 4 с. Если ΠΎΡ‚Π²Π΅Ρ‚ всС Π΅Ρ‰Π΅ Π½Π΅ послСдовал, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTO Π±ΡƒΠ΄Π΅Ρ‚ 8 с, Π·Π°Ρ‚Π΅ΠΌ 16 ΠΈ Ρ‚.Π΄.

Алгоритмы ДТСкобсона (Jacobson) Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ вычислСниС RTO ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΈ RTT ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ RTO ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅. Однако, ΠΊΠΎΠ³Π΄Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ выполняСт ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚, Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° нСопрСдСлСнности ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ (retransmission ambiguity problem). На рис. 22.2 ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Ρ‚Ρ€ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… сцСнария, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… истСкаСт врСмя оТидания ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ:

β–  Π·Π°ΠΏΡ€ΠΎΡ потСрян;

β–  ΠΎΡ‚Π²Π΅Ρ‚ потСрян;

β–  Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTO слишком ΠΌΠ°Π»ΠΎ.

Рис. 22.2. Π’Ρ€ΠΈ сцСнария, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΏΡ€ΠΈ истСчСнии Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ

Когда ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° запрос, ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ, ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΎΠΌΡƒ ΠΈΠ· запросов соотвСтствуСт ΠΎΡ‚Π²Π΅Ρ‚. На рисункС, ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π½ΠΎΠΌ справа, ΠΎΡ‚Π²Π΅Ρ‚ соотвСтствуСт Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌΡƒ запросу, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ Π½Π° Π΄Π²ΡƒΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… рисунках ΠΎΡ‚Π²Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π²Ρ‚ΠΎΡ€ΠΎΠΌΡƒ запросу.

Алгоритм ΠšΠ°Ρ€Π½Π° (Karn) [58] ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ этот сцСнарий Π² соотвСтствии со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌΠΈ, примСняСмыми Π² любом случаС, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‚Π²Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ Π½Π° запрос, ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ€Π°Π·Π°:

β–  Π•сли для запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π° Π±Ρ‹Π»ΠΎ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTT, Π½Π΅ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ для обновлСния ΠΎΡ†Π΅Π½ΠΎΡ‡Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ‹ Π½Π΅ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊΠΎΠΌΡƒ запросу соотвСтствуСт ΠΎΡ‚Π²Π΅Ρ‚.

β–  ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚Π²Π΅Ρ‚ ΠΏΡ€ΠΈΡˆΠ΅Π» Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ истСкло врСмя нашСго Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ для ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTO. Волько ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° запрос, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ Π±Ρ‹Π» ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ, ΠΌΡ‹ измСняСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ RTT ΠΈ снова вычисляСм RTO.

ΠŸΡ€ΠΈ написании Π½Π°ΡˆΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ RTT ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠšΠ°Ρ€Π½Π° нСслоТно, Π½ΠΎ оказываСтся, Ρ‡Ρ‚ΠΎ сущСствуСт ΠΈ Π±ΠΎΠ»Π΅Π΅ изящноС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅. Оно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡΡ… TCP для сСтСй с высокой пропускной ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒΡŽ, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ сСтСй, ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‰ΠΈΡ… Π»ΠΈΠ±ΠΎ ΡˆΠΈΡ€ΠΎΠΊΠΎΠΉ полосой пропускания, Π»ΠΈΠ±ΠΎ большим Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ RTT, Π»ΠΈΠ±ΠΎ ΠΎΠ±ΠΎΠΈΠΌΠΈ этими свойствами (RFC 1323 [53]). ΠšΡ€ΠΎΠΌΠ΅ добавлСния порядкового Π½ΠΎΠΌΠ΅Ρ€Π° ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ запроса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚Ρ€Π°Π·ΠΈΡ‚ΡŒ, ΠΌΡ‹ добавляСм ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΡƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ сСрвСр Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚Ρ€Π°Π·ΠΈΡ‚ΡŒ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, отправляя запрос, ΠΌΡ‹ сохраняСм Π² этой ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Когда ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ ΠΎΡ‚Π²Π΅Ρ‚, ΠΌΡ‹ вычисляСм Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ RTT для этого ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΊΠ°ΠΊ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя минус Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½Π½ΠΎΠΉ сСрвСром Π² своСм ΠΎΡ‚Π²Π΅Ρ‚Π΅. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос нСсСт ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΡƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅ΠΌΡƒΡŽ сСрвСром, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ RTT для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ нСопрСдСлСнности. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сСрвСр Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΡƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΎΠΊ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π»ΡŽΠ±Ρ‹Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹Π΅ Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹, ΠΈ ΠΏΡ€ΠΈ этом Π½Π΅ трСбуСтся, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ сСрвСр синхронизировали часы.

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

БвяТСм Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ всю эту ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ Π²ΠΎΠ΅Π΄ΠΈΠ½ΠΎ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅. ΠœΡ‹ Π½Π°Ρ‡Π½Π΅ΠΌ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main нашСго ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° UDP, прСдставлСнного Π² листингС 8.3, ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠΌ Π² Π½Π΅ΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π° с SERV_PORT Π½Π° 7 (стандартный эхо-сСрвСр, см. Ρ‚Π°Π±Π». 2.1).

Π’ листингС 22.4 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция dg_cli. ЕдинствСнноС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с листингом 8.4 состоит Π² Π·Π°ΠΌΠ΅Π½Π΅ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ sendto ΠΈ recvfrom Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ нашСй Π½ΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ dg_send_recv.

ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ dg_send_recv ΠΈ наши Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ RTT, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½Π° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΌΡ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π² листингС 22.5 Π½Π°ΡˆΡƒ схСму Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… свойств, ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΡ… Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° UDP. ВсС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΈΠΌΠ΅Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ с rtt_, описаны Π΄Π°Π»Π΅Π΅.

Листинг 22.4. Ѐункция dg_cli, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π°Ρ Π½Π°ΡˆΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ dg_send_recv

//rtt/dg_cli.c

 1 #include "unp.h"


 2 ssize_t Dg_send_recv(int, const void*, size_t, void*, size_t,

 3  const SA*, socklen_t);


 4 void

 5 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

 6 {

 7  ssize_t n;

 8  char sendline[MAXLINE], recvline[MAXLINE + 1];


 9  while (Fgets(sendline, MAXLINE, fp) != NULL) {


10   n = Dg_send_recv(sockfd, sendline, strlen(sendline),

11    recvline, MAXLINE, pservaddr, servlen);


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

13   Fputs(recvline, stdout);

14  }

15 }

Листинг 22.5. Π‘Ρ…Π΅ΠΌΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ RTT ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΡ… Π²Ρ‹Π·ΠΎΠ²Π°

static sigjmp_buf jmpbuf;


{


 Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ запроса


 signal(SIGALRM, sig_alrm); /* устанавливаСм ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала */

 rtt_newpack(); /* ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика rexmt Π½ΡƒΠ»Π΅ΠΌ */

sendagain:

 sendto();


 alarm(rtt_start()); /* Π·Π°Π΄Π°Π΅ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ alarm Ρ€Π°Π²Π½Ρ‹ΠΌ RTO */

 if (sigsetjmp(jmpbuf, 1) != 0) {

  if (rtt_timeout()) /* ΡƒΠ΄Π²Π°ΠΈΠ²Π°Π΅ΠΌ RTO, обновляСм ΠΎΡ†Π΅Π½ΠΎΡ‡Π½Ρ‹Π΅ значСния */

   отказываСмся ΠΎΡ‚ Π΄Π°Π»ΡŒΠ½Π΅ΠΉΡˆΠΈΡ… ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ

  goto sendagain; /* повторная ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° */

 }

 do {

  recvfrom();

 } while (Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ порядковый Π½ΠΎΠΌΠ΅Ρ€);

 alarm(0); /* ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ сигнал alarm */

 rtt_stop(); /* вычисляСм RTT ΠΈ обновляСм ΠΎΡ†Π΅Π½ΠΎΡ‡Π½Ρ‹Π΅ значСния */


 ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚


}


void sig_alrm(int signo) {

 siglongjmp(jmpbuf, 1);

}

Если ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ ΠΎΡ‚Π²Π΅Ρ‚, Π½ΠΎ Π΅Π³ΠΎ порядковый Π½ΠΎΠΌΠ΅Ρ€ отличаСтся ΠΎΡ‚ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌΠΎΠ³ΠΎ, ΠΌΡ‹ снова Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ recvfrom, Π½ΠΎ Π½Π΅ отправляСм снова Ρ‚ΠΎΡ‚ ΠΆΠ΅ запрос ΠΈ Π½Π΅ пСрСзапускаСм Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² ΠΊΡ€Π°ΠΉΠ½Π΅ΠΌ ΠΏΡ€Π°Π²ΠΎΠΌ случаС Π½Π° рис. 22.2 послСдний ΠΎΡ‚Π²Π΅Ρ‚, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ Π½Π° ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ запрос, Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Ρ€Π΅ΡˆΠΈΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ запрос (ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π° Π½Π΅Π³ΠΎ ΠΎΡ‚Π²Π΅Ρ‚). Π­Ρ‚ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚ этот ΠΎΡ‚Π²Π΅Ρ‚, ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚, Ρ‡Ρ‚ΠΎ порядковый Π½ΠΎΠΌΠ΅Ρ€ отличаСтся ΠΎΡ‚ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌΠΎΠ³ΠΎ, ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚ ΠΈ снова Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ recvfrom.

ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sigsetjmp ΠΈ siglongjmp, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠ΅ ситуации Π³ΠΎΠ½ΠΎΠΊ с сигналом SIGALRM, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ описали Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 20.5. Π’ листингС 22.6 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° пСрвая Ρ‡Π°ΡΡ‚ΡŒ нашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ dg_send_recv.

Листинг 22.6. Ѐункция dg_send_recv: пСрвая ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π°

//rtt/dg_send_recv.c

 1 #include "unprtt.h"

 2 #include <setjmp.h>


 3 #define RTT_DEBUG


 4 static struct rtt_info rttinfo;

 5 static int rttinit = 0;

 6 static struct msghdr msgsend, msgrecv;

   /* прСдполагаСтся, Ρ‡Ρ‚ΠΎ ΠΎΠ±Π΅ структуры ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π½ΡƒΠ»Π΅ΠΌ */

 7 static struct hdr {

 8  uint32_t seq; /* порядковый Π½ΠΎΠΌΠ΅Ρ€ */

 9  uint32_t ts;  /* ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ */

10 } sendhdr, recvhdr;


11 static void signalrm(int signo);

12 static sigjmp_buf jmpbuf;


13 ssize_t

14 dg_send_recv(int fd, const void *outbuff, size_t outbytes,

15  void *inbuff, size_t inbytes,

16  const SA *destaddr, socklen_t destlen)

17 {

18  ssize_t n;

19  struct iovec iovsend[2], iovrecv[2];

20  if (rttinit == 0) {

21   rtt_init(&rttinfo); /* ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² */

22   rttinit = 1;

23   rtt_d_flag = 1;

24  }

25  sendhdr.seq++;

26  msgsend.msg_name = destaddr;

27  msgsend.msg_namelen = destlen;

28  msgsend.msg_iov = iovsend;

29  msgsend.msg_iovlen = 2;

30  iovsend[0].iov_base = &sendhdr;

31  iovsend[0].iov_len = sizeof(struct hdr);

32  iovsend[1].iov_base = outbuff;

33  iovsend[1].iov_len = outbytes;

34  msgrecv.msg_name = NULL;

35  msgrecv.msg_namelen = 0;

36  msgrecv.msg_iov = iovrecv;

37  msgrecv.msg_iovlen = 2;

38  iovrecv[0].iov_base = &recvhdr;

39  iovrecv[0].iov_len = sizeof(struct hdr);

40  iovrecv[l].iov_base = inbuff;