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

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

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

 // ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² Π²ΠΏΠΎΠ»Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, хотя ΠΈ нСкрасиво

 S := TSocket(Parameter);

 // БвязываСм событиС SockEvents[0] с FD_READ ΠΈ FD_CLOSE

 WSAEventSelect(S, SockEvents[0], FD_READ or FD_CLOSE);

 while True do

 begin

  case WSAWaitForMultipleEvents(3, @SockEvents[0], True, WSA_INFINITE, False) of

  WSA_WAIT_EVENT_0: begin

   WSAEnumNetworkEvents(S, SockEvents[0], NetworkEvents);

   if NetworkEvents.lNetworkEvents and FD_READ > 0 then

    if NetworkEvents.iErrorCode[FD_READ_BIT] = 0 then

    begin

     // ΠŸΡ€ΠΈΡˆΠ»ΠΈ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ

    end

    else

    begin

     // ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка. НуТно ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΎ Π½Π΅ΠΉ ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Π½ΠΈΡ‚ΡŒ

     closesocket(3);

     Exit;

    end;

   if NetworkEvents.lNetworkEvents and FD_CLOSE > 0 then

   begin

    // Бвязь Ρ€Π°Π·ΠΎΡ€Π²Π°Π½Π°

    if NetworkEvents.iErrorCode[FD_CLOSE_BIT] = 0 then begin

     // Бвязь Π·Π°ΠΊΡ€Ρ‹Ρ‚Π° ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ

    end

    else

    begin

     // Бвязь Ρ€Π°Π·ΠΎΡ€Π²Π°Π½Π° Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ сбоя сСти

    end;

    // Π’ любом случаС Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ сокСт ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Π½ΠΈΡ‚ΡŒ

    closesocket(S);

    Exit;

   end;

  end;

  WSA_WAIT_EVENT_0 + 1: begin

   // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ сигнал ΠΎ нСобходимости ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅

   // Π—Π΄Π΅ΡΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΠ΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…

   // ПослС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ событиС Π½ΡƒΠΆΠ½ΠΎ ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ

   ResetEvent(SockEvents[1]);

  end;

  WSA_WAIT_EVENT_0 + 2: begin

   // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ сигнал ΠΎ нСобходимости Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½ΠΈΡ‚ΠΈ

   closesocket;

   ResetEvents(SockEvents[2]);

   Exit;

  end

  end;

 end;

end;

Как ΠΈ Π²ΠΎ всСх ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…, здСсь для краткости Π½Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ΡΡ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ функциями ΠΈ Π½Π΅ ΠΎΡ‚Π»Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰ΠΈΠ΅ ошибки. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, отсутствуСт ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ связи с Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ shutdown.

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

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

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

2.2.8. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования сокСтов с событиями

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

Π‘Π΅Ρ€Π²Π΅Ρ€ Π½Π° асинхронных событиях (ΠΏΡ€ΠΈΠΌΠ΅Ρ€ EventSelectServer Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС) ΠΈΠΌΠ΅Π΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠ±Ρ‰Π΅Π³ΠΎ с рассмотрСнным Ρ€Π°Π½Π΅Π΅ ΠΌΠ½ΠΎΠ³ΠΎΠ½ΠΈΡ‚Π΅Π²Ρ‹ΠΌ сСрвСром (ΠΏΡ€ΠΈΠΌΠ΅Ρ€ MultithreadedServer, см. Ρ€Π°Π·Π΄. 2.1.12). Π’ Π½Π΅ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π½ΠΈΡ‚ΡŒ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ Π½ΠΈΡ‚ΠΈ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π° главная Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ создаСт ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт ΠΈ запускаСт ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΡƒΡŽ Π΅Π³ΠΎ Π½ΠΈΡ‚ΡŒ.

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

Π’ листингС 2.63 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΊΠΎΠ΄ Π½ΠΈΡ‚ΠΈ, Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ (ΠΊΠΎΠ΄ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² LogMessage ΠΈ DoLogMessage ΠΎΠΏΡƒΡ‰Π΅Π½, Ρ‚.ΠΊ. ΠΎΠ½ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π΅Π½ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌΡƒ Π² листингах 2.20 ΠΈ 2.7 соотвСтствСнно).

Листинг 2.63. ΠΠΈΡ‚ΡŒ, Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ

unit ClientThread;

{

 ΠΠΈΡ‚ΡŒ, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰Π°Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

 Π’ыполняСт Ρ†ΠΈΠΊΠ», Π²Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ ΠΏΠΎ Π²Π½Π΅ΡˆΠ½Π΅ΠΌΡƒ сигналу ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки Π½Π° сокСтС. Π£ΠΌΠ΅Π΅Ρ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ сообщСния ΠΏΠΎ Π²Π½Π΅ΡˆΠ½Π΅ΠΌΡƒ сигналу.

}

interface


uses

 Windows, Classes, WinSock, Winsock2_Events, ShutdownConst, SysUtils, SyncObjs;


type

 TClientThread = class(TThread)

 private

  // Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Π»ΠΎΠ³,

  // хранится Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΠ»Π΅, Ρ‚.ΠΊ. ΠΌΠ΅Ρ‚ΠΎΠ΄, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉΡΡ Ρ‡Π΅Ρ€Π΅Π·

  // Synchronize, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².

  FMessage: string;

  // ΠŸΡ€Π΅Ρ„ΠΈΠΊΡ для всСх сообщСний Π»ΠΎΠ³Π°, связанных с Π΄Π°Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

  FHeader: string;

  // Π‘ΠΎΠΊΠ΅Ρ‚ для взаимодСйствия с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

  FSocket: TSocket;

  // Бобытия Π½ΠΈΡ‚ΠΈ

  // FEvents[0] ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для остановки Π½ΠΈΡ‚ΠΈ

  // FEvents[1] ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ сообщСния

  // FEvents[2] связываСтся с событиями FD_READ, FD_WRITE ΠΈ FD_CLOSE

  FEvents; array[0..2] of TWSAEvent;

  // ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ сСкция для доступа ΠΊ Π±ΡƒΡ„Π΅Ρ€Ρƒ исходящих

  FSendBufSection: TCriticalSection;

  // Π‘ΡƒΡ„Π΅Ρ€ исходящих

  FSendBuf: string;

  // Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для Π²Ρ‹Π·ΠΎΠ²Π° Ρ‡Π΅Ρ€Π΅Π· Synchronize

  procedure DoLogMessage;

  // Ѐункция, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‰Π°Ρ, Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»Π° Π»ΠΈ Π½ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ

  function GetFinished: Boolean;

 protected

  procedure Execute; override;

  // Π’Ρ‹Π²ΠΎΠ΄ сообщСния Π² Π»ΠΎΠ³ Π³Π»Π°Π²Π½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΡ‹

  procedure LogMessage(сonst Msg: string);

  // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° исходящих

  function DoSendBuf: Boolean;

 public

  constructor Create(ClientSocket: TSocket; const ClientAddr: TSockAddr);

  destructor Destroy; override;

  // Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ строки Π² Π±ΡƒΡ„Π΅Ρ€ исходящих

  procedure SendString(const S: string);

  // ΠžΡΡ‚Π°Π½ΠΎΠ²ΠΊΠ° Π½ΠΈΡ‚ΠΈ ΠΈΠ·Π²Π½Π΅

  procedure StopThread;

  property Finished: Boolean read GetFinished;

 end;


 ESocketError = class(Exception);


implementation


uses

 MainServerUnit;


{ TClientThread }


// Π‘ΠΎΠΊΠ΅Ρ‚ для взаимодСйствия с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ создаСтся Π² Π³Π»Π°Π²Π½ΠΎΠΉ Π½ΠΈΡ‚ΠΈ,

// Π° сюда пСрСдаСтся Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ конструктора. Для формирования

// Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° сюда ΠΆΠ΅ пСрСдаСтся адрСс ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

constructor TClientThread.Create(ClientSocket: TSocket; const ClientAddr: TSockAddr);