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

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

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

    mtError, [mbOK], 0);

 end;

end;

Π‘Π»ΡƒΡˆΠ°ΡŽΡ‰Π°Ρ" Π½ΠΈΡ‚ΡŒ TListenThread состоит ΠΈΠ· бСсконСчного оТидания ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° сокСтов создаёт Π½ΠΎΠ²Ρ‹ΠΉ сокСт, ΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π½ΠΈΠΌ создаСтся новая Π½ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏΠ° TClientThread (листинг 2.20).

Листинг 2.20. Код "ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅ΠΉ" Π½ΠΈΡ‚ΠΈ

procedure TListenThread.Execute;

 // Π‘ΠΎΠΊΠ΅Ρ‚, созданный для общСния с ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΠΌΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

 ClientSocket: TSocket;

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

 ClientAddr: TSockAddr;

 ClientAddrLen: Integer;

begin

 // НачинаСм бСсконСчный Ρ†ΠΈΠΊΠ»

 repeat

  ClientAddrLen := SizeOf(ClientAddr);

  // ОТидаСм ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

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

  if ClientSocket = INVALID_SOCKET then

  begin

   // Ошибка Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π°

   // происходит Π½Π΅Ρ‡Ρ‚ΠΎ экстраординарноС. ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ

   // Π² этом случаС бСссмыслСнно.

   LogMessage('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' + GetErrorString);

   Break;

  end;

  // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡƒΡŽ  Π½ΠΈΡ‚ΡŒ для обслуТивания ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

  // ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘ΠΌ Π΅ΠΉ сокСт, созданный для взаимодСйствия с Π½ΠΈΠΌ.

  TClientThread.Create(ClientSocket, ClientAddr);

 until False;

 closesocket(FServerSocket);

 LogMessage('Π‘Π΅Ρ€Π²Π΅Ρ€ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ');

 Synchronize(ServerForm.OnStopServer);

end;

ΠœΠ΅Ρ‚ΠΎΠ΄ LogMessage, ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρƒ "ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅ΠΉ" Π½ΠΈΡ‚ΠΈ, эквивалСнтСн Ρ‚ΠΎΠΌΡƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 2.7.

Код Π½ΠΈΡ‚ΠΈ Ρ‚ΠΈΠΏΠ° TClientThread, которая ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° взаимодСйствиС с ΠΎΠ΄Π½ΠΈΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 2.21.

Листинг 2.21. Код Π½ΠΈΡ‚ΠΈ, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰Π΅ΠΉ взаимодСйствиС с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

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

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

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

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

begin

 FSocket := ClientSocket;

 // Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ содСрТит адрСс ΠΈ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

 // Π­Ρ‚ΠΎΡ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒΡΡ ΠΊΠΎ всСм сообщСниям Π² Π»ΠΎΠ³

 // ΠΎΡ‚ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

 FHeader :=

  'Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ' + inet_ntoa(ClientAddr.sin_addr) + ':' +

   IntToStr(ntohs(ClientAddr.sin_port)) + ': ';

 inherited Create(False);

end;


procedure TClientThread.Execute; var Str: string; StrLen: Integer;

begin

 LogMessage('Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ установлСно');

 // НачинаСм Ρ†ΠΈΠΊΠ», ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ

 // соСдинСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈΠ»ΠΈ ΠΈΠ·-Π·Π° ошибки Π² сСти.

 repeat

  // Π§ΠΈΡ‚Π°Π΅ΠΌ Π΄Π»ΠΈΠ½Ρƒ присланной ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ строки ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Π΅ Π² StrLen

  case ReadFromSocket(FSocket, StrLen, SizeOf(StrLen)) of

  0: begin

   LogMessage('ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π» соСдинСниС');

   Break;

  end;

  -1: begin

   LogMessage('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' +

    GetErrorString);

   Break;

  end;

  end;

  // ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π΅ допускаСт строк Π½ΡƒΠ»Π΅Π²ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹

  if StrLen <= 0 then

  begin

   LogMessage('НСвСрная Π΄Π»ΠΈΠ½Π° строки ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' +

    IntToStr(StrLen));

   Break;

  end;

  // Установка Π΄Π»ΠΈΠ½Ρ‹ строки Π² соотвСтствии с ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ

  SetLength(Str, StrLen);

  // Π§Ρ‚Π΅Π½ΠΈΠ΅ строки Π½ΡƒΠΆΠ½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹

  case ReadFromSocket(FSocket, Str[1], StrLen) of

  0: begin

   LogMessage('ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π» соСдинСниС');

   Break;

  end;

  -1: begin

   LogMessage('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' +

    GetErrorString);

   Break;

  end;

  end;

  LogMessage('ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π° строка: ' + Str);

  // ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ строки

  Str :=

   AnsiUpperCase(StringReplace(Str, #0, '#0', [rfReplaceAll]),

    ' (Multithreaded server)';

  // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° строки. ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ΡΡ Π½Π° ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚ большС, Ρ‡Π΅ΠΌ

  // Π΄Π»ΠΈΠ½Π° строки, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ символ #0 Ρ‚ΠΎΠΆΠ΅ ΠΏΠΎΠΏΠ°Π» Π² ΠΏΠ°ΠΊΠ΅Ρ‚

  if send(FSocket, Str[1], Length(Str) + 1, 0) < 0 then

  begin

   LogMessage('Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ: ' +

    GetErrorString);

   Break;

  end;

  LogMessage('ΠšΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ ΠΎΡ‚Π²Π΅Ρ‚: ' + Str);

 until False;

 closesocket(FSocket);

end;


procedure TClientThread.LogMessage(const Msg: string);

begin

 FMessage := FHeader + Msg;

 Synchronize(DoLogMessage);

end;

ΠœΠ΅Ρ‚ΠΎΠ΄ LogMessage здСсь нСсколько Π²ΠΈΠ΄ΠΎΠΈΠ·ΠΌΠ΅Π½Π΅Π½ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΌΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ: ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΡΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΡŽ ΠΎΠ½ добавляСт адрСс ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠ³ Π²ΠΈΠ΄Π΅Ρ‚ΡŒ, с ΠΊΠ°ΠΊΠΈΠΌ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΡ…ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² связано сообщСниС. Π§Ρ‚ΠΎ ΠΆΠ΅ касаСтся ΠΊΠΎΠ΄Π° Execute, Ρ‚ΠΎ Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ практичСски Π½Π΅ отличаСтся ΠΎΡ‚ ΠΊΠΎΠ΄Π° Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ Ρ†ΠΈΠΊΠ»Π° ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π³ΠΎ сСрвСра (см. листинг 2.15). Π­Ρ‚ΠΎ Π½Π΅ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ β€” сообщСниС здСсь читаСтся ΠΈ обрабатываСтся Π΅Π΄ΠΈΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ. Вся Ρ€Π°Π·Π½ΠΈΡ†Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ нСсколько Ρ‚Π°ΠΊΠΈΡ… Π½ΠΈΡ‚Π΅ΠΉ, обСспСчивая ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ сСрвСра с нСсколькими ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ.

Π­Ρ‚ΠΎΡ‚ сСрвСр ΡƒΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΎΠ±Ρ€Π°Π·Π΅Ρ† для подраТания. НуТно Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Ρ‚Ρ€Π°Ρ‚ΠΈΡ‚ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ рСсурсов, ΠΈ поэтому Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Ρ‚Π°ΠΌ, Π³Π΄Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒΡΡ сотни ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, этот сСрвСр ΠΎΡ‡Π΅Π½ΡŒ уязвим ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ DoS-Π°Ρ‚Π°ΠΊΠ°ΠΌ, поэтому ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ сСрвСр цСлСсообразСн Ρ‚Π°ΠΌ. Π³Π΄Π΅ число ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅Π²Π΅Π»ΠΈΠΊΠΎ, Π° Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ DoS-Π°Ρ‚Π°ΠΊ Π½ΠΈΠ·ΠΊΠ°.

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

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

2.1.13. ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ готовности сокСта

Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ Π²Ρ‹Π·Π²Π°Π²ΡˆΡƒΡŽ ΠΈΡ… Π½ΠΈΡ‚ΡŒ, Ссли ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ опСрация Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ, часто Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π·Π°Ρ€Π°Π½Π΅Π΅ Π·Π½Π°Ρ‚ΡŒ, Π³ΠΎΡ‚ΠΎΠ² Π»ΠΈ сокСт ΠΊ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠΌΡƒ (Π±Π΅Π· блокирования) Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ Ρ‚ΠΎΠΉ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. ΠžΡΠ½ΠΎΠ²Π½Ρ‹ΠΌ срСдством опрСдСлСния этого Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ сокСтов слуТит функция select:

function select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): LongInt;

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ оставлСн Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для совмСстимости со старыми вСрсиями Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов: Π² ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… вСрсиях ΠΎΠ½ игнорируСтся. Π’Ρ€ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° содСрТат ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° мноТСства сокСтов (эти мноТСства ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Ρ‚ΠΈΠΏΠΎΠΌ TFDSet), состояниС ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒΡΡ. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС понятиС мноТСства Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΎΠ±Ρ‰Π΅Π³ΠΎ с Ρ‚ΠΈΠΏΠΎΠΌ мноТСство Π² Delphi. Π’ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΉ вСрсии Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов, написанной Π½Π° C, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ макросы, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΎΡ‡ΠΈΡ‰Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ мноТСства, Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ сокСты ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ, Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π»ΠΈ Ρ‚ΠΎΡ‚ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ сокСт Π² мноТСство. Π’ ΠΌΠΎΠ΄ΡƒΠ»Π΅ WinSock эти макросы Π·Π°ΠΌΠ΅Π½Π΅Π½Ρ‹ ΠΎΠ΄Π½ΠΎΠΈΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ ΠΈ функциями (листинг 2.22).

Листинг 2.22. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ‚ΠΈΠΏΠΎΠΌ TFDSet

// УдаляСт сокСт Socket ΠΈΠ· мноТСства FDSet.

procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);


// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚, Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π»ΠΈ сокСт Socket Π² мноТСство FDSet.

function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;


// ДобавляСт сокСт Socket Π² мноТСство FDSet.

procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);


// Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ мноТСство FDSet.

procedure FD_ZERO(var FDSet: TFDSet);

ΠŸΡ€ΠΈ создании ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ° TFDSet Π² Ρ‚ΠΎΠΉ области памяти, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΎΠ½Π° Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚, ΠΌΠΎΠ³ΡƒΡ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, ΡΠ²Π»ΡΡŽΡ‰ΠΈΠ΅ΡΡ, ΠΏΠΎ сути Π΄Π΅Π»Π°, "мусором". Из-Π·Π° этого мусора Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ FD_CLR, FD_ISSET, ΠΈ FD_SET Π½Π΅ смогут Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° FD_ZERO ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ мусор, создавая пустоС мноТСство. Π’Ρ‹Π·ΠΎΠ² ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ FD_XXX Π΄ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° FD_ZERO ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ нСпрСдсказуСмым Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌ.

ΠœΡ‹ Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π½ΠΎ Π½Π΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠΌ здСсь описаниС Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ структуры Ρ‚ΠΈΠΏΠ° TFDSet. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ FD_XXX ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с мноТСством, Π½Π΅ зная этой структуры. ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π² Windows ΠΈ Π² Unix Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ устройство этого Ρ‚ΠΈΠΏΠ° сущСствСнно различаСтся, Π½ΠΎ благодаря использованию этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΊΠΎΠ΄ остаСтся пСрСносимым.

Π’ Windows максимальноС количСство сокСтов, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π² сСбС мноТСство TFDSet, опрСдСляСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ константы FD_SETSIZE. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ 64. Π’ C/C++ отсутствуСт Ρ€Π°Π·Π΄Π΅Π»ΡŒΠ½Π°Ρ компиляция ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π² Ρ‚ΠΎΠΌ смыслС, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½Π° сущСствуСт Π² Delphi, поэтому ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π² этих языках ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠ΅Π½ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ константы FD_SETSIZE ΠΏΠ΅Ρ€Π΅Π΄ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов, ΠΈ это ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ измСнСнию Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ структуры Ρ‚ΠΈΠΏΠ° TFDSet (Ρ‚ΠΎΡ‡Π½Π΅Π΅, Ρ‚ΠΈΠΏΠ° FDSet β€” Π² C/C++ ΠΎΠ½ называСтся Ρ‚Π°ΠΊ). К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Π² Delphi ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π½Π°Π΄Π΅ΠΆΠ½ΠΎ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Ρ‹ ΠΎΡ‚ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ влияния Π΄Ρ€ΡƒΠ³ Π½Π° Π΄Ρ€ΡƒΠ³Π°, поэтому ΠΊΠ°ΠΊ Π±Ρ‹ ΠΌΡ‹ Π½ΠΈ пСрСопрСдСляли константу FD_SETSIZE Π² своСм ΠΌΠΎΠ΄ΡƒΠ»Π΅, Π½Π° ΠΌΠΎΠ΄ΡƒΠ»Π΅ WinSock это Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ отразится. Π’ Delphi приходится ΠΏΡ€ΠΈΠ±Π΅Π³Π°Ρ‚ΡŒ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ способу измСнСния количСства сокСтов Π² мноТСствС: для этого слСдуСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ свой Ρ‚ΠΈΠΏ, эквивалСнтный ΠΏΠΎ структурС TFDSet, Π½ΠΎ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΈΠ½ΠΎΠ΅ количСство памяти для хранСния сокСтов (структуру TFDSet ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ·Π½Π°Ρ‚ΡŒ ΠΈΠ· исходного ΠΊΠΎΠ΄Π° модуля WinSock). Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° структуры Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ. А Π²ΠΎΡ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ FD_XXX, ΠΊ соТалСнию, Π½Π΅ смогут Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π½ΠΎΠ²ΠΎΠΉ структурой, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ компилятор Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ строгого соотвСтствия Ρ‚ΠΈΠΏΠΎΠ² для ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²-ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. Но, ΠΎΠΏΡΡ‚ΡŒ ΠΆΠ΅, ΠΏΡ€ΠΈ нСобходимости ΠΎΡ‡Π΅Π½ΡŒ Π»Π΅Π³ΠΊΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π°Π½Π°Π»ΠΎΠ³ΠΈ этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для своСй структуры.