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

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

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

 FD_ZERO(SockSet);

 FD_SET(MainSocket, SockSet);

 if select(0, @SockSet, nil, nil, @Timeout) = SOCKET_ERROR then

  raise ESocketException.Create('Ошибка ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ готовности ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ сокСта: ' +

   GetErrorString);

 // Если функция select оставила MainSocket Π² мноТСствС, Π·Π½Π°Ρ‡ΠΈΡ‚,

 // зафиксировано ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΈ функция accept Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚

 // ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Π½ΠΈΡ‚ΠΈ.

 if FD_ISSET(MainSocket, SockSet) then

 begin

  ClientSockAddrLen := SizeOf(ClientSockAddr);

  // ΠŸΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Для общСния с Π½ΠΈΠΌ создаСтся

  // Π½ΠΎΠ²Ρ‹ΠΉ сокСт, дСскриптор ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ помСщаСтся Π² ClientSocket.

  ClientSocket :=

   accept(MainSocket, @ClientSockAddr, @ClientSockAddrLen);

  if ClientSocket = INVALID_SOCKET then raise

   ESocketException.Create(

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

  // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π² динамичСской памяти Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр TConnection

  // ΠΈ заполняСм Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅ΠΌΡƒΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ

  New(NewConnection);

  NewConnection.ClientSocket := ClientSocket;

  NewConnection.ClientAddr :=

   Format('%u.%u.%u.%u:%u',

    Ord(ClientSockAddr.sin_addr.S_un_b.s_bl),

    Ord(ClientSockAddr.sin_addr.S_un_b.s_b2),

    Ord(ClientSockAddr.sin_addr.S_un_b.s_b3),

    Ord(ClientSockAddr.sin_addr.S_un_b.s_b4),

    ntohs(ClientSockAddr.sin_port));

  NewConnection.Deleted := False;

  // ДобавляСм соСдинСниС Π² список

  Connections.Add(NewConnection);

  WriteLn(OemString('Зафиксировано ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ с адрСса ' +

   NewConnection.ClientAddr));

 end;

 // Π’Π΅ΠΏΠ΅Ρ€ΡŒ провСряСм Π³ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ всСх сокСтов ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΡ…ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ².

 // Π’Π°ΠΊ ΠΊΠ°ΠΊ мноТСство SockSet Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ FT_SETSIZE

 // элСмСнтов, Π° Ρ€Π°Π·ΠΌΠ΅Ρ€ списка Connections ΠΌΡ‹ Π½ΠΈΠ³Π΄Π΅ Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ,

 // приходится Ρ€Π°Π·Π±ΠΈΠ²Π°Ρ‚ΡŒ Connections Π½Π° "куски" Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ Π½Π΅ Π±ΠΎΠ»Π΅Π΅

 // FD_SETSIZE ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ этот список ΠΏΠΎ частям.

 // ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρƒ нас появляСтся Π΄Π²Π° Ρ†ΠΈΠΊΠ»Π° - внСшний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ повторяСтся

 // ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π·, сколько Ρƒ нас Π±ΡƒΠ΄Π΅Ρ‚ кусков, ΠΈ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ

 // повторяСтся ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π·, сколько элСмСнтов Π² ΠΎΠ΄Π½ΠΎΠΌ кускС.

 for J := 0 to Ceil(Connections.Count, FD_SETSIZE) - 1 do

 begin

  FD_ZERO(SockSet);

  for I := FD_SETSIZE * J to Min(FD_SETSIZE * (J + 1) - 1, Connections.Count - 1) do

   FD_SET(PConnection(Connections[I])^.ClientSocket, SockSet);

  if select(0, @SockSet, nil, nil, @Timeout) = SOCKET_ERROR then

   raise ESocketException.Create(

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

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

  // ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ для Π½ΠΈΡ… ProcessSocketMessage. Π’ этом Π΅ΡΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ

  // риск, Ρ‚.ΠΊ. для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ select оставила сокСт Π² мноТСствС,

  // достаточно, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°,

  // Π° Π½Π΅ всС сообщСниС. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ такая ситуация,

  // ΠΊΠΎΠ³Π΄Π° сСрвСр ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ сообщСния, Π½ΠΎ ΡƒΠΆΠ΅ пытаСтся

  // ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ сообщСниС Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Π½ΠΈΡ‚ΠΈ,

  // Π½ΠΎ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ блокирования Π½Π° Π΄ΠΎΠ»Π³ΠΎΠ΅ врСмя ΠΌΡ‹ ΠΎΡ†Π΅Π½ΠΈΠ²Π°Π΅ΠΌ ΠΊΠ°ΠΊ

  // ΠΊΡ€Π°ΠΉΠ½Π΅ Π½ΠΈΠ·ΠΊΡƒΡŽ, Ρ‚.ΠΊ. ΠΎΡΡ‚Π°Π²ΡˆΠ°ΡΡΡ Ρ‡Π°ΡΡ‚ΡŒ сообщСния, скорСС всСго,

  // ΠΏΡ€ΠΈΠ΄Π΅Ρ‚ достаточно быстро, ΠΈ поэтому ΠΈΠ΄Π΅ΠΌ Π½Π° Ρ‚Π°ΠΊΠΎΠΉ риск.

  for I := FD_SETSIZE * J to Min(FD_SETSIZE * (J + 1) - 1, Connections.Count - 1) do

   if FD_ISSET(PConnection(Connections[I])^.ClientSocket, SockSet) then

    ProcessSocketMessage(PConnection(Connections[I])^);

 end;

 // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΠ»Π΅ Deleted Ρƒ всСх соСдинСний. Π’Π΅, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ…

 // ΠΎΠ½ΠΎ Ρ€Π°Π²Π½ΠΎ True, Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ: Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ сокСт, освобоТдаСм ΠΏΠ°ΠΌΡΡ‚ΡŒ,

 // удаляСм ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΈΠ· списка. Π¦ΠΈΠΊΠ» ΠΈΠ΄Π΅Ρ‚ с ΠΊΠΎΠ½Ρ†Π° списка ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ,

 // ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² Ρ…ΠΎΠ΄Π΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ†ΠΈΠΊΠ»Π° вСрхняя Π³Ρ€Π°Π½ΠΈΡ†Π° списка

 // ΠΌΠΎΠΆΠ΅Ρ‚ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ, ΠΈ Ρ†ΠΈΠΊΠ» for снизу Π²Π²Π΅Ρ€Ρ… ΠΌΠΎΠ³ Π±Ρ‹ привСсти

 // ΠΊ появлСнию индСксов Π²Π½Π΅ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°.

 for I := Connections.Count - 1 downto 0 do

  if PConnection(Connections[I])^.Deleted then

  begin

   closesocket(PConnection(Connections[I])^.ClientSocket);

   Dispose(PConnection(Connections[I]));

   Connections.Delete(I);

  end;

 Sleep(100);

until False; 

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ceil ΠΈ Min, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‚ΡΡ здСсь, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΈΠΌΡ‘Π½Π½Ρ‹ΠΌΠΈ функциями ΠΈΠ· модуля Math. Но этот ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π½Π΅ Π²ΠΎ всС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ поставки Delphi, ΠΈ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² любом Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ поставки Delphi, ΠΌΡ‹ описали ΠΈΡ… здСсь ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ (листинг 2.27).

Листинг 2.27. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ceil ΠΈ Min

// Ѐункция Ceil Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ наимСньшСС Ρ†Π΅Π»ΠΎΠ΅ число X, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰Π΅Π΅

// нСравСнству X >= А / Π’

function Ceil(A, B: Integer): Integer;

begin

 Result := A div B;

 if A mod Π’ <> 0 then Inc(Result);

end;


// Ѐункция Min Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ мСньшСС ΠΈΠ· Π΄Π²ΡƒΡ… чисСл

function Min(А, Π’: Integer): Integer;

begin

 if A < Π’ then Result := A

 else Result := B;

end;

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

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

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

ΠœΠ½ΠΎΠ³ΠΎΠ½ΠΈΡ‚Π΅Π²ΠΎΠΉ сСрвСр Π² этом ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ Π½Π°Π΄Π΅ΠΆΠ½Π΅Π΅: Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ сообщСниС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Ρƒ Π½ΠΈΡ‚ΡŒ, которая взаимодСйствуСт с этим ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ, Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ влияя Π½Π° ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π½ΠΈΡ‚ΠΈ, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠ΅ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ.

Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ сСрвСр Π±ΠΎΠ»Π΅Π΅ устойчивым ΠΊ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ дСйствиям ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΌΠΎΠΆΠ½ΠΎ, Ссли ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ€ΠΎΠ²Π½ΠΎ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π°ΠΉΡ‚ΠΎΠ², сколько ΠΏΡ€ΠΈΡˆΠ»ΠΎ. Π­Ρ‚ΠΎ услоТнит сСрвСр, Ρ‚.ΠΊ. придСтся ΠΌΠ΅ΠΆΠ΄Ρƒ "сСансами связи с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ" ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ сколько Π±Π°ΠΉΡ‚ΠΎΠ² Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½ΠΎ Π² ΠΏΡ€ΠΎΡˆΠ»Ρ‹ΠΉ Ρ€Π°Π·. Однако это ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ ΠΏΡ€ΠΈ опСрациях чтСния, Ρ‡Ρ‚ΠΎ сущСствСнно повысит Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ сСрвСра. Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π° Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ эту Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ сСрвСрС, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΌ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ сокСты. Π’ сСрвСрС Π½Π° основС select это дСлаСтся ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ.

2.1.15. ΠΠ΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ

Π Π°Π½Π΅Π΅ ΠΌΡ‹ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ с функциями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π½Π°Π΄ΠΎΠ»Π³ΠΎ ΠΏΡ€ΠΈΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅ΠΉ ΠΈΡ… Π½ΠΈΡ‚ΠΈ, Ссли дСйствиС Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. Π­Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept, recv, recvfrom, send, sendto ΠΈ connect (Π² дальнСйшСм Π² этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ recvfrom ΠΈ sendto, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Π² смыслС блокирования эквивалСнтны функциям recv ΠΈ send соотвСтствСнно, ΠΈ всС, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ здСсь сказано ΠΎ recv ΠΈ send, ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ ΠΊ recvfrom ΠΈ sendto). Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π½Π΅ всСгда ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, поэтому Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ сокСтов прСдусмотрСн особый Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹ сокСтов β€” Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ. Π­Ρ‚ΠΎΡ‚ Ρ€Π΅ΠΆΠΈΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ установлСн ΠΈΠ»ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ Π΄ΠΌ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ сокСта ΠΈΠ½Π΄ΠΈΠ²ΠΈΠ΄ΡƒΠ°Π»ΡŒΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ioctlsocket, ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ:

function ioctlsocket(s: TSocket; cmd: DWORD; var arg: u_long): Integer;

Данная функция ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для выполнСния Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… логичСски ΠΌΠ°Π»ΠΎ связанных ΠΌΠ΅ΠΆΠ΄Ρƒ собой дСйствий. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² ΠΏΠ΅Ρ€Π²Ρ‹Ρ… вСрсий Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов Π±Ρ‹Π»ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ ΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ Π½Π° количСствС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈ дальшС ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π΅ΠΏΠΎΡ…ΠΎΠΆΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΎΠ΄Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ. Но вСрнСмся ΠΊ ioctlsocket. Π•Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ cmd опрСдСляСт дСйствиС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ выполняСт функция, Π° Ρ‚Π°ΠΊΠΆΠ΅ смысл ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° arg. Допустимы Ρ‚Ρ€ΠΈ значСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° cmd: SIOCATMARK, FIONREAD ΠΈ FIONBIO. ΠŸΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ SIOCATMARK ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ arg рассматриваСтся ΠΊΠ°ΠΊ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ: Π² Π½Π΅ΠΌ возвращаСтся ноль, Ссли Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ высокоприоритСтныС Π΄Π°Π½Π½Ρ‹Π΅, ΠΈ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ссли Ρ‚Π°ΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… Π½Π΅Ρ‚ (ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΠ³ΠΎΠ²ΠΎΡ€Π΅Π½ΠΎ, ΠΌΡ‹ Π² этой ΠΊΠ½ΠΈΠ³Π΅ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΊΠ°ΡΠ°Ρ‚ΡŒΡΡ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ высокоприоритСтных Π΄Π°Π½Π½Ρ‹Ρ…). 

ΠŸΡ€ΠΈ cmd, Ρ€Π°Π²Π½ΠΎΠΌ FIONREAD, Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ arg возвращаСтся Ρ€Π°Π·ΠΌΠ΅Ρ€ Π΄Π°Π½Π½Ρ‹Ρ…, находящихся Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта, Π² Π±Π°ΠΉΡ‚Π°Ρ…. ΠŸΡ€ΠΈ использовании TCP это число Ρ€Π°Π²Π½ΠΎ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ количСству ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π° ΠΎΠ΄ΠΈΠ½ Π²Ρ‹Π·ΠΎΠ² recv. Для UDP это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ суммарному Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ всСх находящихся Π² Π±ΡƒΡ„Π΅Ρ€Π΅ Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ (Π½Π°ΠΏΠΎΠΌΠ½ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ нСсколько Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌ Π·Π° ΠΎΠ΄ΠΈΠ½ Π²Ρ‹Π·ΠΎΠ² recv нСльзя). Ѐункция ioctlsocket с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ FIONREAD ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ наличия Π΄Π°Π½Π½Ρ‹Ρ… с Ρ†Π΅Π»ΡŒΡŽ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²Π° recv Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° это ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ, ΠΈΠ»ΠΈ для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Π²Ρ‹Π·ΠΎΠ²Π° recv Π² Ρ†ΠΈΠΊΠ»Π΅ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½Π° вся информация.