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

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

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

ΠœΡ‹ Π΅Ρ‰Π΅ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΠΈ написаниС нашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ str_cli: Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 15.2 ΠΌΡ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ Π΅Π΅ Π²Π΅Ρ€ΡΠΈΡŽ с использованиСм Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, Π° Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 23.3 β€” Π²Π΅Ρ€ΡΠΈΡŽ, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΡƒΡŽ с ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ.

6.8. Π­Ρ…ΠΎ-сСрвСр TCP (ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅)

ВСрнСмся ΠΊ Π½Π°ΡˆΠ΅ΠΌΡƒ эхо-сСрвСру TCP ΠΈΠ· Ρ€Π°Π·Π΄Π΅Π»ΠΎΠ² 5.2 ΠΈ 5.3. ΠŸΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅ΠΌ сСрвСр ΠΊΠ°ΠΊ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ процСсс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ любого числа ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², вмСсто Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fork ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌΡƒ процСссу для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ этот ΠΊΠΎΠ΄, взглянСм Π½Π° структуры Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ для отслСТивания ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². На рис. 6.11 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ состояниС сСрвСра Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ установил соСдинСниС.

Рис. 6.11. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ установил соСдинСниС

Π£ сСрвСра имССтся ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ дСскриптор, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π½Π° рисункС Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ.

Π‘Π΅Ρ€Π²Π΅Ρ€ обслуТиваСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π±ΠΎΡ€ дСскрипторов для чтСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½Π° рис. 6.12. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ сСрвСр запускаСтся Π² ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½ΠΎΠΌ (foreground) Ρ€Π΅ΠΆΠΈΠΌΠ΅, Π° дСскрипторы 0, 1 ΠΈ 2 ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ стандартным ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ Π²Π²ΠΎΠ΄Π°, Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ ошибок. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ доступным для ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ сокСта дСскриптором являСтся дСскриптор 3. Массив Ρ†Π΅Π»Ρ‹Ρ… чисСл client содСрТит дСскрипторы присоСдинСнного сокСта для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ВсС элСмСнты этого массива ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ -1.

Рис. 6.12. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… для сСрвСра TCP с ΠΎΠ΄Π½ΠΈΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΌ сокСтом

ЕдинствСнная нСнулСвая запись Π² Π½Π°Π±ΠΎΡ€Π΅ дСскрипторов β€” это запись для ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ сокСта, ΠΈ поэтому ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π΅Π½ 4.

Когда ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ устанавливаСт соСдинСниС с нашим сСрвСром, ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ дСскриптор становится доступным для чтСния ΠΈ сСрвСр Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept. Новый присоСдинСнный дСскриптор, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ accept, Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π½ΠΎΠΌΠ΅Ρ€ 4, Ссли Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ Π²Ρ‹ΡˆΠ΅ прСдполоТСния. На рис. 6.13 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ соСдинСниС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° с сСрвСром.

Рис. 6.13. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP послС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ устанавливаСт соСдинСниС

Π’Π΅ΠΏΠ΅Ρ€ΡŒ наш сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ присоСдинСнный сокСт Π² своСм массивС client, ΠΈ присоСдинСнный сокСт Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² Π½Π°Π±ΠΎΡ€ дСскрипторов. ИзмСнившиСся структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Π½Π° рис. 6.14.

Рис. 6.14. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… послС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ установлСно соСдинСниС с ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

Π§Π΅Ρ€Π΅Π· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ врСмя Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ устанавливаСт соСдинСниС, ΠΈ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ сцСнарий, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π½Π° рис. 6.15.

Рис. 6.15. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP послС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ установлСно соСдинСниС со Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

Новый присоСдинСнный сокСт (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ Π½ΠΎΠΌΠ΅Ρ€ 5) Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ Π² памяти, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ‡Π΅Π³ΠΎ структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° рис. 6.16.

Рис. 6.16. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… послС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ установлСно соСдинСниС со Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

Π”Π°Π»Π΅Π΅ ΠΌΡ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ своС соСдинСниС. TCP-ΠΊΠ»ΠΈΠ΅Π½Ρ‚ отправляСт сСгмСнт FIN, прСвращая Ρ‚Π΅ΠΌ самым дСскриптор Π½ΠΎΠΌΠ΅Ρ€ 4 Π½Π° сторонС сСрвСра Π² Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ для чтСния. Когда наш сСрвСр считываСт этот присоСдинСнный сокСт, функция readline Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΡƒΠ»ΡŒ. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ сокСт, ΠΈ соотвСтствСнно ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ наши структуры Π΄Π°Π½Π½Ρ‹Ρ…. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ client[0] устанавливаСтся Π² -1, Π° дСскриптор 4 Π² Π½Π°Π±ΠΎΡ€Π΅ дСскрипторов устанавливаСтся Π² Π½ΡƒΠ»ΡŒ. Π­Ρ‚ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° рис. 6.17. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ maxfd Π½Π΅ измСняСтся.

Рис. 6.17. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… послС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Ρ€Π°Π·Ρ€Ρ‹Π²Π°Π΅Ρ‚ соСдинСниС

Π˜Ρ‚Π°ΠΊ, ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ приходят ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, ΠΌΡ‹ записываСм дСскриптор ΠΈΡ… присоСдинСнного сокСта Π² ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ свободный элСмСнт массива client (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π² ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ -1). Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ присоСдинСнный сокСт Π² Π½Π°Π±ΠΎΡ€ дСскрипторов для чтСния. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ maxi β€” это наибольший ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ индСкс Π² массивС client, Π° пСрСмСнная maxfd (плюс ΠΎΠ΄ΠΈΠ½) β€” это Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select. ЕдинствСнным ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π½Π° количСство обслуТиваСмых сСрвСром ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² являСтся минимальноС ΠΈΠ· Π΄Π²ΡƒΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ: FD_SETSIZE ΠΈ максимального числа дСскрипторов, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ допускаСтся для Π΄Π°Π½Π½ΠΎΠ³ΠΎ процСсса ядром (ΠΎ Ρ‡Π΅ΠΌ ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ Π² ΠΊΠΎΠ½Ρ†Π΅ Ρ€Π°Π·Π΄Π΅Π»Π° 6.3).

Π’ листингС 6.3 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° пСрвая ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° этой вСрсии сСрвСра.

Листинг 6.3. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ процСсс ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select: инициализация

//tcpcliserv/tcpservselect01.c

 1 #include "unp.h"


 2 int

 3 main(int argc, char **argv)

 4 {

 5  int i, maxi, maxfd, listenfd, connfd, sockfd;

 6  int nready, client[FD_SETSIZE],

 7  ssize_t n;

 8  fd_set rset, allset;

 9  char buf[MAXLINE];

10  socklen_t clilen;

11  struct sockaddr_in cliaddr, servaddr;


12  listenfd = Socket(AF_INET, SOCK_STREAM, 0);


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

14  servaddr.sin_family = AF_INET;

15  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

16  servaddr.sin_port = htons(SERV_PORT);


17  Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));


18  Listen(listenfd, LISTENQ);


19  maxfd = listenfd; /* инициализация */

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

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

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

23  FD_ZERO(&allset);

24  FD_SET(listenfd, &allset);

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ сокСта ΠΈ инициализация Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select

12-24 Π­Ρ‚Π°ΠΏΡ‹ создания ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ сокСта Ρ‚Π΅ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ Ρ€Π°Π½ΡŒΡˆΠ΅: Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ socket, bind ΠΈ listen. ΠœΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ Ρ‚ΠΎΠΌ условии, Ρ‡Ρ‚ΠΎ СдинствСнный дСскриптор, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select Π²Ρ‹Π±Π΅Ρ€Π΅ΠΌ, ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ являСтся ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΌ сокСтом.

Вторая ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 6.4.

Листинг 6.4. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΉ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ процСсс ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select: Ρ†ΠΈΠΊΠ»

//tcpcliserv/tcpservselect01.c

25  for (;;) {

26   rset = allset; /* присваиваниС значСния структурС */

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


28   if (FD_ISSET(listenfd, &rset)) { /* соСдинСниС с Π½ΠΎΠ²Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ */

29    clilen = sizeof(cliaddr);

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


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

32     if (client[i] < 0) {

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

34      break;

35     }

36    if (i == FD_SETSIZE)

37     err_quit("too many clients");


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

39    if (connfd > maxfd)

40     maxfd = connfd; /* для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select */

41    if (i > maxi)

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


43    if (--nready <= 0)

44     continue; /* большС Π½Π΅Ρ‚ дСскрипторов, Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… для чтСния */

45   }

46   for (i = 0; i <= maxi; i++) { /* провСряСм всС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅

                                      Π΄Π°Π½Π½Ρ‹Ρ… */

47    if ((sockfd - client[i]) < 0)

48     continue;

49    if (FD_ISSET(sockfd, &rset)) {

50     if ((n = Read(sockfd, buf, MAXLINE)) == 0) {

51      /* соСдинСниС Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ */

52      Close(sockfd);

53      FD_CLR(sockfd, &allset);

54      client[i] = -1;

55     } else

56      Writen(sockfd, line, n);


57     if (--nready <= 0)

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

59    }

60   }

61  }

62 }

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select

26-27 Π€ΡƒΠ½ΠΊΡ†ΠΈΡ select ΠΆΠ΄Π΅Ρ‚, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ установлСно Π½ΠΎΠ²ΠΎΠ΅ клиСнтскоС соСдинСниС ΠΈΠ»ΠΈ Π½Π° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ соСдинСнии Π½Π΅ ΠΏΡ€ΠΈΠ±ΡƒΠ΄ΡƒΡ‚ Π΄Π°Π½Π½Ρ‹Π΅, сСгмСнт FIN ΠΈΠ»ΠΈ сСгмСнт RST.

ΠŸΡ€ΠΈΠ½ΡΡ‚ΠΈΠ΅ Π½ΠΎΠ²Ρ‹Ρ… соСдинСний с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept

28-45 Π•сли ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ сокСт Π³ΠΎΡ‚ΠΎΠ² для чтСния, Π½ΠΎΠ²ΠΎΠ΅ соСдинСниС установлСно. ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ обновляСм наши структуры Π΄Π°Π½Π½Ρ‹Ρ…. Для записи присоСдинСнного сокСта ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ нСзадСйствованный элСмСнт массива client. Число Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… дСскрипторов ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ, ΠΈ Ссли ΠΎΠ½ΠΎ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ†ΠΈΠΊΠ» for. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ select, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… дСскрипторов.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… соСдинСний

46-60 ΠšΠ°ΠΆΠ΄ΠΎΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ клиСнтскоС соСдинСниС провСряСтся Π½Π° ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ Ρ‚ΠΎΠ³ΠΎ, содСрТится Π»ΠΈ Π΅Π³ΠΎ дСскриптор Π² Π½Π°Π±ΠΎΡ€Π΅ дСскрипторов, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ select. Если Π΄Π°, Ρ‚ΠΎ ΠΈΠ· этого дСскриптора считываСтся строка, присланная ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ, ΠΈ отраТаСтся ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ. Если ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ соСдинСниС, функция read Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΡƒΠ»ΡŒ ΠΈ ΠΌΡ‹ обновляСм структуры ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.