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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «О Ρ‡Ρ‘ΠΌ Π½Π΅ ΠΏΠΈΡˆΡƒΡ‚ Π² ΠΊΠ½ΠΈΠ³Π°Ρ… ΠΏΠΎ DelphiΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 62

Автор А. Π“Ρ€ΠΈΠ³ΠΎΡ€ΡŒΠ΅Π²

На ΠΏΠ΅Ρ€Π²ΠΎΠΌ шагС Ρ†ΠΈΠΊΠ»Π° создаётся мноТСство сокСтов, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ всС сокСты, содСрТащиСся Π² массивС. Π’ этом мСстС Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½Π° ваТная ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ сокСтов Π² массивС Π½Π΅ большС 64-Ρ…. Если ΠΈΡ… Π±ΡƒΠ΄Π΅Ρ‚ большС, Ρ‚ΠΎ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ лишниС сокСты Π² мноТСство Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ FD_SET ΠΈ, ΡΠΎΠΎΡ‚вСтствСнно, эти сокСты Π²Ρ‹ΠΏΠ°Π΄ΡƒΡ‚ ΠΈΠ· дальнСйшСго рассмотрСния, Ρ‚.Π΅. Π΄Π°ΠΆΠ΅ Ссли ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΡ€ΠΈΡˆΠ»Π΅Ρ‚, сСрвСр этого Π½Π΅ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚. Π Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ трСмя способами. Π‘Π°ΠΌΡ‹ΠΉ простой β€” это ΠΎΡ‚ΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π² ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ лишним ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ. Для этого сразу послС Π²Ρ‹Π·ΠΎΠ²Π° accept Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ для Π½ΠΎΠ²ΠΎΠ³ΠΎ сокСта closesocket. Π’Ρ‚ΠΎΡ€ΠΎΠΉ способ β€” это ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ количСства сокСтов Π² мноТСствС, ΠΊΠ°ΠΊ это Π±Ρ‹Π»ΠΎ описано Ρ€Π°Π½Π΅Π΅. Π’ этом случаС всС Ρ€Π°Π²Π½ΠΎ остаСтся Ρ‚Π° ΠΆΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, хотя Ссли ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ число сокСтов Π² мноТСствС достаточно большим, ΠΎΠ½Π° практичСски исчСзаСт. И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ сокСты Π½Π° нСсколько ΠΏΠΎΡ€Ρ†ΠΈΠΉ, для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ select ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ. Π­Ρ‚ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ услоТнСния ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ сСйчас Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ бСсконСчноС ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅. ΠŸΡ€ΠΈ Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠΈ сокСтов Π½Π° ΠΏΠΎΡ€Ρ†ΠΈΠΈ это ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ ΠΈΠ·-Π·Π° отсутствия Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… сокСтов Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΏΠΎΡ€Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ смоТСт ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΡ€Ρ†ΠΈΠΈ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ сокСты, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Π΅ΡΡ‚ΡŒ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ раздСлСния сокСтов Π½Π° ΠΏΠΎΡ€Ρ†ΠΈΠΈ Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСн Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅.

ΠŸΡ€ΠΈ создании мноТСства ΠΎΠ½ΠΎ сначала очищаСтся, Π° ΠΏΠΎΡ‚ΠΎΠΌ Π² Π½Π΅Π³ΠΎ Π² Ρ†ΠΈΠΊΠ»Π΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ сокСты. Для Π»ΡŽΠ±ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΊΡ€Π°Ρ‚ΠΊΠΈΡ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ Π΅ΡΡ‚ΡŒ сущСствСнно Π±ΠΎΠ»Π΅Π΅ быстрый способ формирования мноТСства, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π½Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π½ΠΈ Ρ†ΠΈΠΊΠ»Ρ‹, Π½ΠΈ FD_ZERO, Π½ΠΈ FD_SET:

Move((PChar(Sockets) - 4)^, FDSet, Length(Sockets) * SizeOf(TSocket) + SizeOf(Integer));

ΠŸΠΎΡ‡Π΅ΠΌΡƒ такая конструкция Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅ΠΌ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΈΠ·ΡƒΡ‡ΠΈΠ² ΠΏΠΎ справкС Delphi, ΠΊΠ°ΠΊ хранятся Π² памяти динамичСскиС массивы, Π° ΠΏΠΎ MSDN β€” структуру Ρ‚ΠΈΠΏΠ° FDSET. Π’Π΅ΠΌ ΠΆΠ΅, ΠΊΡ‚ΠΎ ΠΏΠΎ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ Π½Π΅ Π·Π°Ρ…ΠΎΡ‡Π΅Ρ‚ Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ΡŒΡΡ, Π½Π°ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ Π½ΠΈΠΊΠΎΠ³Π΄Π° ΠΈ Π½ΠΈ ΠΏΡ€ΠΈ ΠΊΠ°ΠΊΠΈΡ… ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°Ρ… Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² Π½Π΅ΡƒΠΌΠ΅Π»Ρ‹Ρ… Ρ€ΡƒΠΊΠ°Ρ… ΠΎΠ½Π° прСвращаСтся Π² ΠΌΠΈΠ½Ρƒ Π·Π°ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ дСйствия, ΠΈΠ·-Π·Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ошибки ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡΠ²ΠΈΡ‚ΡŒΡΡ Π² самых Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹Ρ… мСстах ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Π’Ρ‚ΠΎΡ€ΠΎΠΉ шаг β€” это собствСнно Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ оТидания готовности сокСтов с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select. Π“ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ ΠΊ записи ΠΈ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ высокоприоритСтной ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ нас Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Π½Π΅ интСрСсуСт, поэтому ΠΌΡ‹ ограничиваСмся Π·Π°Π΄Π°Π½ΠΈΠ΅ΠΌ мноТСства readfds. Π’ нашСм простом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… дСйствий, Ссли Π½ΠΈ ΠΎΠ΄ΠΈΠ½ сокСт Π½Π΅ Π³ΠΎΡ‚ΠΎΠ², поэтому послСдний ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΎΠΆΠ΅ Ρ€Π°Π²Π΅Π½ nil, Ρ‡Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅, Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ΅ Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ΠΎΠΌ.

Π’Ρ€Π΅Ρ‚ΠΈΠΉ шаг выполняСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select, Ρ‚.Π΅. Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· сокСтов находится Π² состоянии готовности. На этом шагС ΠΌΡ‹ провСряСм сокСты, созданныС для взаимодСйствия с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ Π½Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… итСрациях Ρ†ΠΈΠΊΠ»Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept. Π­Ρ‚ΠΈ сокСты Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π² массивС сокСтов, начиная с элСмСнта с индСксом 1. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π² Ρ†ΠΈΠΊΠ»Π΅ просматриваСт всС сокСты ΠΈ, Ссли ΠΎΠ½ΠΈ находятся Π² состоянии готовности, выполняСт ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ чтСния.

На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ странным, ΠΏΠΎΡ‡Π΅ΠΌΡƒ для ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€Π° элСмСнтов массива Π²Ρ‹Π±Ρ€Π°Π½ Ρ†ΠΈΠΊΠ» while, Π° Π½Π΅ for. Но Π² дальнСйшСм ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ массива Π²ΠΎ врСмя выполнСния Ρ†ΠΈΠΊΠ»Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ. ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΆΠ΅ Ρ†ΠΈΠΊΠ»Π° for Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π΅Π³ΠΎ Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΈ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°ΡŽΡ‚ΡΡ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ячСйках памяти, ΠΈ дальнСйшСС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, Π·Π°Π΄Π°ΡŽΡ‰ΠΈΡ… эти Π³Ρ€Π°Π½ΠΈΡ†Ρ‹, Π½Π΅ измСняСт эти Π³Ρ€Π°Π½ΠΈΡ†Ρ‹. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ это ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π² случаС ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ массива Ρ†ΠΈΠΊΠ» for Π½Π΅ остановится Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ²ΡˆΠ΅ΠΉΡΡ Π΄Π»ΠΈΠ½Π΅, Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΆΠ΅ Π½Π΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ элСмСнтам, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ прСдсказуСмым послСдствиям. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅ Ρ†ΠΈΠΊΠ» while, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ условиС продолТСния Ρ†ΠΈΠΊΠ»Π° Π·Π°Π½ΠΎΠ²ΠΎ вычисляСтся ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π΅Π³ΠΎ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ.

Напомним, Ρ‡Ρ‚ΠΎ функция select ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ Π΅ΠΉ мноТСства Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π² Π½ΠΈΡ… ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ лишь сокСты, находящиСся Π² состоянии готовности. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π³ΠΎΡ‚ΠΎΠ² Π»ΠΈ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ сокСт, достаточно с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ FD_ISSET ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π»ΠΈ ΠΎΠ½ Π² мноТСство FDSet. Если Π²Ρ…ΠΎΠ΄ΠΈΡ‚, Ρ‚ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ для Π½Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ recv. Если эта функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π·Π½Π°Ρ‡ΠΈΡ‚, Π΄Π°Π½Π½Ρ‹Π΅ Π² Π±ΡƒΡ„Π΅Ρ€Π΅ Π΅ΡΡ‚ΡŒ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡ… Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ ΠΈ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚. Если функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 0 ΠΈΠ»ΠΈ -1 (SOCKET_ERROR) Π·Π½Π°Ρ‡ΠΈΡ‚, соСдинСниС Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ ΠΈΠ»ΠΈ Ρ€Π°Π·ΠΎΡ€Π²Π°Π½ΠΎ, ΠΈ Π΄Π°Π½Π½Ρ‹ΠΉ сокСт большС Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ связанныС с Π½ΠΈΠΌ рСсурсы (closesocket) ΠΈ ΡƒΠ±Ρ€Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΈΠ· массива сокСтов (ΠΊΠ°ΠΊ Ρ€Π°Π· Π½Π° этом шагС Ρ€Π°Π·ΠΌΠ΅Ρ€ массива ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ). ΠŸΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ сокСты ΡΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π½Π° ΠΎΠ΄Π½Ρƒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π²Π»Π΅Π²ΠΎ, поэтому ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ†ΠΈΠΊΠ»Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ, ΠΈΠ½Π°Ρ‡Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ сокСт Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΏΡƒΡ‰Π΅Π½.

И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Π½Π° Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠΌ шагС ΠΌΡ‹ провСряСм состояниС готовности исходного сокСта, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ хранится Π² Π½ΡƒΠ»Π΅Π²ΠΎΠΌ элСмСнтС массива. Π’Π°ΠΊ ΠΊΠ°ΠΊ этот сокСт находится Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ оТидания соСдинСния, для Π½Π΅Π³ΠΎ состояниС готовности ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ соСдинСний появились ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹, ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ сокСты для взаимодСйствия с этими ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ.

Π₯отя ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π²ΠΏΠΎΠ»Π½Π΅ работоспособСн, слСдуСт ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ сСрвСра. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ Π½Π΅ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚ΡŒΡΡ ΠΊ Π½Π΅ΠΌΡƒ ΠΊΠ°ΠΊ ΠΊ Π΄ΠΎΠ³ΠΌΠ΅, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ Π² вашСм случаС ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚. Π¦Π΅Π½Π½ΠΎΡΡ‚ΡŒ этого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select, Π° Π½Π΅ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π΄Π°Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π° всС случаи ΠΆΠΈΠ·Π½ΠΈ.

2.1.14. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select

Рассмотрим Π΄Π²Π° практичСских ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select для получСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ готовности сокСта. Оба ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° станут Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅ΠΌ рассмотрСнных Ρ€Π°Π½Π΅Π΅.

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

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

НСсмотря Π½Π° эти измСнСния, новая вСрсия UDP-Ρ‡Π°Ρ‚Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Ρ‚ΡŒΡΡ сообщСниями со старой, Ρ‚.ΠΊ. ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» ΠΎΠ±ΠΌΠ΅Π½Π° остался Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌ.

Листинг 2.24. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° готовности сокСтов ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ сообщСния ΠΎΡ‚ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°

// РСакция Π½Π° Ρ‚Π°ΠΉΠΌΠ΅Ρ€. Π‘ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ, Π·Π°Π΄Π°Π½Π½ΠΎΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ΠΎΠΌ,

// провСряСм, Π½Π΅ ΠΏΡ€ΠΈΡˆΠ»ΠΈ Π»ΠΈ сообщСния, ΠΈ Ссли ΠΏΡ€ΠΈΡˆΠ»ΠΈ,

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΈΡ….

procedure TChatForm.TimerChatTimer(Sender: TObject);

var

 // ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²ΠΎ сокСтов для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select.

 // Π‘ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ сокСт FSocket.

 SocketSet: TFDSet;

 // Π’Π°ΠΉΠΌ-Π°ΡƒΡ‚ для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select

 Timeout: TTimeVal;

 // Π‘ΡƒΡ„Π΅Ρ€ для получСния сообщСния.

 // Π Π°Π·ΠΌΠ΅Ρ€ Ρ€Π°Π²Π΅Π½ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ UDP-Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹

 Buffer: array[0..65506] of Byte;

 Msg: string;

 // АдрСс, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΡˆΠ»ΠΎ сообщСниС

 RecvAddr: TSockAddr;

 RecvLen, AddrLen: Integer;

begin

 // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ мноТСство сокСтов,

 // Ρ‚.Π΅. ΠΎΡ‡ΠΈΡ‰Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΎΡ‚ случайного мусора

 FD_ZERO(SocketSet);

 // ДобавляСм Π² это мноТСство сокСт FSocket

 FD_SET(FSocket, SocketSet);

 // УстанавливаСм Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ Ρ€Π°Π²Π½Ρ‹ΠΌ Π½ΡƒΠ»ΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹

 // функция select Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΠΆΠ΄Π°Π»Π°, Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π»Π°

 // Π³ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ сокСтов Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π°.

 Timeout.tv_sec := 0;

 Timeout.tv_usec := 0;

 // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π³ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ сокСта для чтСния

 if select(0, @SocketSet, nil, nil, @Timout) = SOCKET_ERROR then

 begin

  AddMessageToLog('Ошибка ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ готовности сокСта: ' + GetErrorString);

  Exit;

 end;

 // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, оставила Π»ΠΈ функция select сокСт Π² мноТСствС.

 //Если оставила, Π·Π½Π°Ρ‡ΠΈΡ‚, Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта Π΅ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅.

 if FD_ISSET(FSocket, SocketSet) then

 begin

  AddrLen := SizeOf(RecvAddr); // ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡƒ

  RecvLen :=

   recvfrom(FSocket, Buffer, SizeOf(Buffer), 0, RecvAddr, AddrLen);

  // Π’Π°ΠΊ ΠΊΠ°ΠΊ UDP Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ соСдинСниС, ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ recvfrom