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 Π² ΡΠΈΠΊΠ»Π΅ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΈΠ· Π±ΡΡΠ΅ΡΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½Π° Π²ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ.