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

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

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

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

int WSARecvFrom(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr FAR *lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;


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

function WSARecvFrom(S: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; var NumberOfBytesRecvd: DWORD; var Flags: DWORD; lpFrom: PSockAddr; lpFromLen: PInteger; lpOverlapped: FWSAOverlapped; lpCompletionRoutine: TWSAOverlappedCompletionRoutine): Integer;

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ lpFrom ΠΈ lpFromLen этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, слуТащиС для получСния адрСса отправитСля, эквивалСнтны ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ recvfrom, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ ΡƒΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Π·Π½Π°ΠΊΠΎΠΌΡ‹. Π’ ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΌ WSARecvFrom Π²Π΅Π΄Π΅Ρ‚ сСбя Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ WSARecv, поэтому ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Π½Π΅ΠΉ.

Для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSASend ΠΈ WSASendTo, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΡ‹ (листинг 2.75).

Листинг 2.75. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSASend ΠΈ WSASendTo

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

int WSASend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);

int WSASendTo(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, const struct sockaddr FAR *lpTo, int iToLen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);


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

function WSASend(S: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; var NumberOfBytesRecvd: DWORD; Flags: DWORD; lpOverlapped: PWSAOverlapped; lpCompletionRoutine: TWSAOverlappedCompletionRoutine): Integer;

function WSASendTo(S: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; var NumberOfBytesRecvd: DWORD; Flags: DWORD; var AddrTo: TSockAddr; ToLen: Integer; lpOverlapped: PWSAOverlapped; lpCompletionRoutine: TWSAOverlappedCompletionRoutine): Integer;

Если Π²Ρ‹ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ с функциями WSARecv, send ΠΈ sendto, Ρ‚ΠΎ смысл ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ WSASend ΠΈ WSASendTo Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π²Π°ΠΌ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π΅Π½, поэтому ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΌΡ‹ ΠΈΡ… Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ. Но ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρ„Π»Π°Π³ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΈΡ….

ΠŸΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒ Π² ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Π²Π²ΠΎΠ΄Π΅-Π²Ρ‹Π²ΠΎΠ΄Π΅ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ достаточно Ρ€Π΅Π΄ΠΊΠΎ. Но Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSASend/WSASendTo ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ΅ ΠΌΠ½ΠΎΠ³ΠΎΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π½Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠΌΠ΅ΡŽΡ‚ фиксированный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ. Для Ρ‚Π°ΠΊΠΈΡ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΈΡ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€Ρ‹ с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ ΠΈ с Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΈ, ΠΏΠΎΠ»ΡŒΠ·ΡƒΡΡΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· нСсвязных Π±ΡƒΡ„Π΅Ρ€ΠΎΠ², ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΅Π³ΠΎ ΡΡ€Π΅Π΄Π½ΡŽΡŽ Ρ‡Π°ΡΡ‚ΡŒ.

2.2.10. Π‘Π΅Ρ€Π²Π΅Ρ€, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ Π²Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ рассмотрим созданиС сСрвСра Π½Π° основС ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° Π½Π° основС ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ (ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π° с использованиСм событий Π΅ΡΡ‚ΡŒ Π² MSDN Π² описании Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ WSARecv β€” ΠΈ WSASend). ΠŸΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ Π²Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для ΠΎΠ±ΠΌΠ΅Π½Π° Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ "запрос-ΠΎΡ‚Π²Π΅Ρ‚", поэтому ΠΌΡ‹ вновь вСрнСмся ΠΊ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌΡƒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ прСдусматриваСт ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ сСрвСром сообщСний ΠΏΠΎ собствСнному ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Π½ΠΈΡŽ. На ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ называСтся OverlappedServΠ΅r.

Как ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ соСдинСния создаСтся экзСмпляр записи TConnection, которая Π½Π° этот Ρ€Π°Π· выглядит Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² листингС 2.76.

Листинг 2.76. Π’ΠΈΠΏ TConnection

// Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ соСдинСнии с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ:

// ClientSocket - сокСт, созданный для взаимодСйствия с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

// ClientAddr - ΡΡ‚Ρ€ΠΎΠΊΠΎΠ²ΠΎΠ΅ прСдставлСниС адрСса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

// MsgSite - Π΄Π»ΠΈΠ½Π° строки, получаСмая ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

// Msg - строка, получаСмая ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈΠ»ΠΈ отправляСмая Π΅ΠΌΡƒ

// Offset - количСство Π±Π°ΠΉΡ‚ΠΎΠ², ΡƒΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

// ΠΈΠ»ΠΈ отправляСмых Π΅ΠΌΡƒ Π½Π° Π΄Π°Π½Π½ΠΎΠΌ этапС

// BytesLeft - сколько Π±Π°ΠΉΡ‚ΠΎΠ² ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

// ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΅ΠΌΡƒ Π½Π° Π΄Π°Π½Π½ΠΎΠΌ этапС

// Overlapped - структура для выполнСния ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

PConnection = ^TConnection;

TConnection = record

 ClientSocket: TSocket;

 ClientAddr: string;

 MsgSize: Integer;

 Msg: string;

 Offset: Integer;

 BytesLeft: Integer;

 Overlapped: TWSAOverlapped;

end;

ОсновноС ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ этого Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° Ρ‚ΠΈΠΏΠ° TConnection ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ примСнялся Ρ€Π°Π½Π΅Π΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… NonBlockingServer ΠΈ AsyncSelectServer (см. Ρ€Π°Π·Π΄. 2.1.16 ΠΈ 2.2.6, Π° Ρ‚Π°ΠΊΠΆΠ΅ листинг 2.31) β€” это отсутствиС поля Phase, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ ΡΡ‚Π°ΠΏ взаимодСйствия с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ. РазумССтся, Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ OverlappedServer взаимодСйствиС с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ Ρ‚Π°ΠΊΠΆΠ΅ разбиваСтся Π½Π° Ρ‚Ρ€ΠΈ этапа, Π½ΠΎ рСализуСтся Π΄Ρ€ΡƒΠ³ΠΎΠΉ способ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Π»ΠΈΡ‡Π°Ρ‚ΡŒ этапы β€” для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ этапа создаСтся своя ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ.

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

ИспользованиС ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ для всСх Ρ‚Ρ€Π΅Ρ… этапов ΠΈ распознаваниС Π² Π½Π΅ΠΉ этапов с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ поля Phase Π² случаС ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ сСрвСра Π² качСствС ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ упраТнСния.

ПолС Overlapped содСрТит структуру TWSAOverlapped, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° нСпосрСдствСнно Π½Π΅ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, ΠΎΠ½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° эту структуру Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WSARecv ΠΈ WSASend. Напомним, Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ нСсколько ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, Π½ΠΎ Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· этих ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ свой экзСмпляр TWSAOverlapped. Π“Π°ΠΊ ΠΊΠ°ΠΊ Π² нашСм случаС с ΠΎΠ΄Π½ΠΈΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΌΡ‹ создаСм ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ экзСмпляру TWSAOverlapped Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

Ѐункция для ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² сущСствуСт β€” это AcceptEx, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ познакомимся Π² Ρ€Π°Π·Π΄. 2.2.12. Но ΠΎΠ½Π° Π½Π΅ΡƒΠ΄ΠΎΠ±Π½Π° ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ совмСстно с WSARecv ΠΈ WSASend, особСнно Π² Ρ‚Π°ΠΊΠΎΠΌ строго Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ языкС, ΠΊΠ°ΠΊ Delphi. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡƒΠΆΠ΅ ΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Π½Π½ΠΎΠΉ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ асинхронных сокСтов Π½Π° сообщСниях. Код запуска сСрвСра OverlappedServer выглядит ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΎ ΠΊΠΎΠ΄Ρƒ запуска AsyncSelectServer (см. листинг 2.30): Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ создаСтся сокСт, ставится Π² Ρ€Π΅ΠΆΠΈΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ, Π° Π·Π°Ρ‚Π΅ΠΌ Π΅Π³ΠΎ событиС FD_ACCEPT привязываСтся ΠΊ ΡΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΡŽ WM_ACCEPTMESSAGE. 

Π‘Π°ΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ WM_ACCEPTMESSAGE выглядит Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (листинг 2.77).

Листинг 2.77. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сообщСния WM_ACCEPTMESSAGE

procedure TServerForm.WMAcceptMessage(var Msg: TWMSocketMessage);

var

 NewConnection: PConnection;

 // Π‘ΠΎΠΊΠ΅Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСтся для вновь ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 ClientSocket: TSocket;

 // АдрСс ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 ClientAddr: TSockAddr;

 // Π”Π»ΠΈΠ½Π° адрСса

 AddrLen: Integer;

 // АргумСнт для ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° сокСта Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ

 Arg: u_long;

 // Π‘ΡƒΡ„Π΅Ρ€ для ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ чтСния

 Buf: TWSABuf;

 NumBytes, Flags: DWORD;

begin

 // БтрахуСмся ΠΎΡ‚ "Ρ‚ΡƒΠΏΠΎΠΉ" ошибки

 if Msg.Socket <> FServerSocket then

  raise ESocketError.Create(

   'ВнутрСнняя ошибка сСрвСра - Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ сСрвСрный сокСт');

 // ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π½Π° сокСтС, Ссли ΠΎΠ½Π° Π΅ΡΡ‚ΡŒ

 if Msg.SockError <> 0 then

 begin

  MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:'#13#10 +

   GetErrorString(Msg.SockError) +

   #13#10'Π‘Π΅Ρ€Π²Π΅Ρ€ Π±ΡƒΠ΄Π΅Ρ‚ ocΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½', mtError, [mbOK], 0);

  ClearConnections;

  closesocket(FServerSocket);

  OnStopServer;

  Exit;

 end;

 // БтрахуСмся ΠΎΡ‚ Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½ΠΎΠΉ "Ρ‚ΡƒΠΏΠΎΠΉ" ошибки

 if Msg.SockEvent <> FD_ACCEPT then

  raise ESocketError.Create(

   'ВнутрСнняя ошибка сСрвСра - Π½Π΅Π²Π΅Ρ€Π½ΠΎΠ΅ событиС Π½Π° сокСтС');

 AddrLen := SizeOf(TSockAddr);

 ClientSocket := accept(FServerSocket, @ClientAddr, @AddrLen);

 if ClientSocket = INVALID_SOCKET then

 begin

  // Если ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠ°Ρ ошибка - WSAEWOULDBLOCK, это просто ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚

  // Ρ‡Ρ‚ΠΎ Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π½Π΅Ρ‚, Π° Π²ΠΎΠΎΠ±Ρ‰Π΅ всС Π° порядкС,

  // поэтому ΠΎΡˆΠΈΠ±ΠΊΡƒ WSAEWOULDBLOCK ΠΌΡ‹ просто ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ. ΠŸΡ€ΠΎΡ‡ΠΈΠ΅ ΠΆΠ΅

  // ошибки ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС ΡΠ΅Ρ€ΡŒΠ΅Π·Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ,

  // ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ остановки сСрвСра.

  if WSAGetLastError <> WSAEWOULDBLOCK then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:'#13#10 +

    GetErrorString + #13#10'Π‘Π΅Ρ€Π²Π΅Ρ€ Π±ΡƒΠ΄Π΅Ρ‚ остановлСн',

    mtError, [mbOK], 0);

   ClearConnections;

   closesocket(FServerSocket);

   OnStopServer;

  end;

 end

 else

 begin

  // Новый сокСт наслСдуСт свойства ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ сокСта.

  // Π’ частности, ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² асинхронном Ρ€Π΅ΠΆΠΈΠΌΠ΅,

  // ΠΈ Π΅Π³ΠΎ событиС FD_ACCEPT связано с сообщСниСм WM_ACCEPTMESSAGE.

  // Π’Π°ΠΊ ΠΊΠ°ΠΊ Π½Π°ΠΌ это ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ, отмСняСм асинхронный

  // Ρ€Π΅ΠΆΠΈΠΌ ΠΈ Π΄Π΅Π»Π°Π΅ΠΌ сокСт Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ.

  if WSAAsyncSelect(ClientSocket, Handle, 0, 0) = SOCKET_ERROR then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ асинхронного Ρ€Π΅ΠΆΠΈΠΌΠ° ' +

    'ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ сокСта:'#13#10 + GetErrorString,

    mtError, [mbOK], 0);

   closesocket(ClientSocket);