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

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

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

Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ноль Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ SOCKET_ERROR β€” ΠΏΡ€ΠΈ ошибкС.

Если ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°ΠΌΠΈ стСка TCP/IP, старыС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅ Π½ΠΎΠ²Ρ‹Ρ…, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ нСпосрСдствСнно Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ прСобразования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² выраТСниях. ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π½ΠΎΠ²Ρ‹ΠΌΠΈ функциями для получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° слСдуСт Π·Π°Π²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, поэтому эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ цСлСсообразны Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π΅Π΄ΠΈΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°ΠΌΠΈ. ПослСдняя функция, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ здСсь рассмотрим, Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ прямых Π°Π½Π°Π»ΠΎΠ³ΠΎΠ² срСди старых Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. НазываСтся ΠΎΠ½Π° WSADuplicateSocket ΠΈ слуТит для копирования дСскриптора сокСта Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс. ΠŸΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSADuplicateSocket ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 2.47.

Листинг 2.47. Ѐункция WSADuplicateSocket

// ***** ОписаниС на C++ *****

int WSADuplicateSocket(SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo);


// ***** ОписаниС на Delphi *****

function WSADuplicateSocket(S: TSocket; dwProcessID: DWORD; var ProtocolInfo: TWSAProtocolInfo): Integer;

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ S Π·Π°Π΄Π°Π΅Ρ‚ сокСт, дСскриптор ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ dwProcessID β€” ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° копия, функция ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π² структуру ProtocolInfo ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡƒΡŽ для создания ΠΊΠΎΠΏΠΈΠΈ дСскриптора Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссом. Π—Π°Ρ‚Π΅ΠΌ эта структура Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ процСссу, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ пСрСдаст Π΅Π΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ WSASocket ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ свою копию дСскриптора для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄Π°Π½Π½Ρ‹ΠΌ сокСтом.

Ѐункция WSADuplicateSocket Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ноль ΠΏΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΈ SOCKET_ERROR β€” Π² случаС ошибки. Как ΠΌΡ‹ ΠΏΠΎΠΌΠ½ΠΈΠΌ, сокСт являСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, внутрСнняя структура ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ остаСтся скрытой ΠΎΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΉ Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ дСскриптором сокСта β€” Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Ѐункция WSADuplicateSocket позволяСт Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ дСскриптор для ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ сокСта. Π‘Ρ‚Π°Ρ€Ρ‹ΠΉ ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ дСскриптор становятся Ρ€Π°Π²Π½ΠΎΠΏΡ€Π°Π²Π½Ρ‹ΠΌΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ сокСт, Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ всС Π΅Π³ΠΎ дСскрипторы с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ closesocket. Если Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π±ΡƒΡ„Π΅Ρ€ сокСта ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π΄Π°Π½Π½Ρ‹Π΅, ΠΈΡ… ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ чтСния, поэтому совмСстноС использованиС ΠΎΠ΄Π½ΠΎΠ³ΠΎ сокСта Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ синхронизации ΠΈΡ… Ρ€Π°Π±ΠΎΡ‚Ρ‹. MSDN Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅Ρ‚ Ρ‚Π°ΠΊΡƒΡŽ схСму Ρ€Π°Π±ΠΎΡ‚Ρ‹, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΎΠ΄Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ создаёт сокСт ΠΈ устанавливаСт соСдинСниС, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ сокСт Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, которая Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ Π²Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄. ΠŸΠ΅Ρ€Π²Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΈ этом Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ свой дСскриптор. Π’Π°ΠΊΠΎΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹ позволяСт ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΈ совмСстном доступС Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ ΠΊ ΠΎΠ΄Π½ΠΎΠΌΡƒ сокСту.

ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ функция WSADuplicateSocket ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для копирования дСскрипторов ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ процСссами. Π Π°Π·Π½Ρ‹Π΅ Π½ΠΈΡ‚ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса Π½Π΅ Π½ΡƒΠΆΠ΄Π°ΡŽΡ‚ΡΡ Π² этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚.ΠΊ., Π½Π°Ρ…ΠΎΠ΄ΡΡΡŒ Π² ΠΎΠ΄Π½ΠΎΠΌ адрСсном пространствС, ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΎΠ΄Π½ΠΈΠΌ ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ дСскриптором.

2.2.5. Асинхронный Ρ€Π΅ΠΆΠΈΠΌ, основанный Π½Π° сообщСниях

ВсС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с сокСтами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ рассматривали Ρ€Π°Π½ΡŒΡˆΠ΅, являлись синхронными. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ Ρ‚Π°ΠΊΠΈΠ΅ сокСты, Π΄ΠΎΠ»ΠΆΠ½Π° сама врСмя ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Ρ‚Π΅ΠΌ ΠΈΠ»ΠΈ ΠΈΠ½Ρ‹ΠΌ способом, ΠΏΡ€ΠΈΡˆΠ»ΠΈ Π»ΠΈ Π΄Π°Π½Π½Ρ‹Π΅, установлСна Π»ΠΈ связь ΠΈ Ρ‚.ΠΏ. АсинхронныС сокСты ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ увСдомлСния ΠΎ событиях, происходящих с сокСтом: поступлСнии Π΄Π°Π½Π½Ρ‹Ρ…, освобоТдСнии мСста Π² Π±ΡƒΡ„Π΅Ρ€Π΅, Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΈ Ρ‚.ΠΏ. Π’Π°ΠΊΠΎΠΉ способ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для событийно-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹Ρ… для Windows. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° асинхронных сокСтов Π²ΠΏΠ΅Ρ€Π²Ρ‹Π΅ появилась Π² WinSock 1 ΠΈ Π±Ρ‹Π»Π° основана Π½Π° сообщСниях, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π»ΠΈΡΡŒ ΠΎΠΊΠΎΠ½Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ. Π’ WinSock 2 этот асинхронный Ρ€Π΅ΠΆΠΈΠΌ остался Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡΡ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΎΠ΅ сообщСниС ΠΊΠ°ΠΊΠΎΠΌΡƒ ΠΎΠΊΠ½Ρƒ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ события Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‰Π΅ΠΌ Π΅Π³ΠΎ сокСтС.

Асинхронный Ρ€Π΅ΠΆΠΈΠΌ с ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ΠΌ Ρ‡Π΅Ρ€Π΅Π· сообщСния устанавливаСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ WSAAsyncSelect, ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ:

function WSAAsyncSelect(S: TSocket; HWindow: HWND; wMsg: u_int; lEvent: LongInt): Integer;

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ S опрСдСляСт сокСт, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ устанавливаСтся асинхронный Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ HWindow β€” дСскриптор ΠΎΠΊΠ½Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ сообщСния, wMsg β€” сообщСниС, a lEvent Π·Π°Π΄Π°Π΅Ρ‚ события, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ сообщСния. Для этого ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ константы, комбинация ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π·Π°Π΄Π°Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ события. ΠœΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ здСсь всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ события, остановимся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° самых Π³Π»Π°Π²Π½Ρ‹Ρ… (Ρ‚Π°Π±Π». 2.2).


Π’Π°Π±Π»ΠΈΡ†Π° 2.2. АсинхронныС события сокСта

Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ FD_READ Π‘ΠΎΠΊΠ΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ² ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ FD_WRITE Π‘ΠΎΠΊΠ΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ² ΠΊ записи FD_ACCEPT Π’ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сокСта Π΅ΡΡ‚ΡŒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для сокСтов, находящихся Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ оТидания ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ) FD_CONNECT Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ установлСно (ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для сокСтов, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹Π·Π²Π°Π½Π° функция connect ΠΈΠ»ΠΈ аналогичная Π΅ΠΉ) FD_CLOSE Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ² WSAAsyncSelect для ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ сокСта отмСняСт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ². Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ выполнСния ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° Ρ„ΠΎΡ€ΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сообщСния, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Π³ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ сокСта ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ, Π° Π³ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ ΠΊ записи Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ сообщСния (листинг 2.48).

Листинг 2.48. ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSAAsyncSelect

WSAAsyncSelect(S, Form1.Handle, WM_USER, FD_WRITE);

// Π’Ρ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ

WSAAsyncSelect(S, Form1.Handle, WM_USER, FD_READ);

// Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΠΊΠ½ΠΎ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ увСдомлСния ΠΎ возмоТности записи

WSAAsyncSelect связываСт с сообщСниСм ΠΈΠΌΠ΅Π½Π½ΠΎ сокСт, Π° Π½Π΅ Π΅Π³ΠΎ дСскриптор. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ссли Π΄Π²Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΎΠ΄ΠΈΠ½ сокСт (копия дСскриптора ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±Ρ‹Π»Π° создана с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSADuplicateSocket), ΠΈ пСрвая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ WSAAsyncSelect со своим дСскриптором, Π° Π·Π°Ρ‚Π΅ΠΌ вторая β€” со своим, Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² WSAAsyncSelect, сдСланный Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ Π²Ρ‹Π·ΠΎΠ², сдСланный Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ.

Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ сообщСния ΠΏΡ€ΠΈ готовности сокСта ΠΊΠ°ΠΊ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ, Ρ‚Π°ΠΊ ΠΈ ΠΊ записи, Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄.

WSAAsyncSelect(S, Form1.Handle, WM_USER, FD_READ or FD_WRITE);

ΠŸΡ€ΠΈ нСобходимости с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ or ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ большСС число констант.

Из сказанного слСдуСт, Ρ‡Ρ‚ΠΎ нСльзя ΡΠ²ΡΠ·Π°Ρ‚ΡŒ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ событиями ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ сокСта Ρ€Π°Π·Π½Ρ‹Π΅ сообщСния (ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ сообщСния Ρ€Π°Π·Π½Ρ‹ΠΌ ΠΎΠΊΠ½Π°ΠΌ), Ρ‚.ΠΊ. ΠΏΡ€ΠΈ ΠΎΠ΄Π½ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ WSAAsyncSelect ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ дСскриптор ΠΎΠΊΠ½Π° ΠΈ ΠΎΠ΄ΠΈΠ½ Π½ΠΎΠΌΠ΅Ρ€ сообщСния, Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ² этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, с Π΄Ρ€ΡƒΠ³ΠΈΠΌ дСскриптором ΠΈ/ΠΈΠ»ΠΈ Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ, ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ. Ѐункция WSAAsyncSelect ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ сокСт Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ. Если Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ асинхронный сокСт Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅, послС Π²Ρ‹Π·ΠΎΠ²Π° WSAAsyncSelect трСбуСтся пСрСвСсти Π΅Π³ΠΎ Π² этот Ρ€Π΅ΠΆΠΈΠΌ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.

Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ связываСтся с асинхронным сокСтом, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹ΠΌ. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ€ Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ ΠΎΡ‚ WM_USER ΠΈ Π²Ρ‹ΡˆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Ρƒ со стандартными сообщСниями.

ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сообщСния Π΅Π³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ wParam содСрТит дСскриптор сокСта, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ событиС. МладшСС слово lParam содСрТит ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠ΅Π΅ событиС (ΠΎΠ΄Π½Ρƒ ΠΈΠ· констант FD_XXX), Π° ΡΡ‚Π°Ρ€ΡˆΠ΅Π΅ слово β€” ΠΊΠΎΠ΄ ошибки Ссли ΠΎΠ½Π° ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π°. Для выдСлСния ΠΊΠΎΠ΄Π° события ΠΈ ΠΊΠΎΠ΄Π° ошибки ΠΈΠ· lParam Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ WinSock прСдусмотрСны макросы WSAGETSELECTEVENT ΠΈ WSAGETSELECTERROR соотвСтствСнно. Π’ ΠΌΠΎΠ΄ΡƒΠ»Π΅ WinSock ΠΎΠ½ΠΈ Π·Π°ΠΌΠ΅Π½Π΅Π½Ρ‹ функциями WSAGetSelectEvent ΠΈ WSAGetSelectError. Одно сообщСниС ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ± ΠΎΠ΄Π½ΠΎΠΌ событии Π½Π° сокСтС. Если ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ нСсколько событий, Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎΠΊΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ нСсколько сообщСний.

Π‘ΠΎΠΊΠ΅Ρ‚, созданный ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept, наслСдуСт Ρ€Π΅ΠΆΠΈΠΌ Ρ‚ΠΎΠ³ΠΎ сокСта, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ принял соСдинСния. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ссли сокСт, находящийся Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ оТидания ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, являСтся асинхронным, Ρ‚ΠΎ ΠΈ сокСт, ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ accept, Π±ΡƒΠ΄Π΅Ρ‚ асинхронным, ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Π½Π°Π±ΠΎΡ€ Π΅Π³ΠΎ событий Π±ΡƒΠ΄Π΅Ρ‚ связан с Ρ‚Π΅ΠΌ ΠΆΠ΅ сообщСниСм, Ρ‡Ρ‚ΠΎ ΠΈ Ρƒ исходного сокСта.

Рассмотрим ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ· пСрСчислСнных событий.

Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ FD_READ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π±ΡƒΡ„Π΅Ρ€ сокСта ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ (Ссли Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° WSAAsyncSelect, Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ Ρ‚Π°ΠΊΠΈΠ΅ события, Π² Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚ΠΎ событиС Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚). Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ сообщСниС помСщаСтся Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎΠΊΠ½Π°, дальнСйшая гСнСрация Ρ‚Π°ΠΊΠΈΡ… сообщСний для этого сокСта блокируСтся, Ρ‚.Π΅. ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊ появлСнию Π½ΠΎΠ²Ρ‹Ρ… сообщСний (ΠΏΡ€ΠΈ этом сообщСния, связанныС с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ событиями этого сокСта ΠΈΠ»ΠΈ с событиСм FD_READ Π΄Ρ€ΡƒΠ³ΠΈΡ… сокСтов, Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ ΠΏΠΎΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ нСобходимости Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎΠΊΠ½Π°). ГСнСрация сообщСний снова Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° функция для чтСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° сокСта (это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ функция recv, recvfrom, WSARecv ΠΈΠ»ΠΈ WSARecvFrom, ΠΌΡ‹ Π² Π΄Π°Π»ΡŒΠ½Π΅ΠΉΡˆΠ΅ΠΌ Π±ΡƒΠ΄Π΅ΠΌ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ recv, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π²Π΅Π΄ΡƒΡ‚ сСбя Π² этом ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ).