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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Delphi. Π’Ρ€ΡŽΠΊΠΈ ΠΈ эффСкты». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 50

Автор Π’Π°Π»Π΅Ρ€ΠΈΠΉ Борисок

ProcessMessage(AThread.Connection, AThread.Connection.ReadLn);

end;

procedure TfrmServer.TCPServerConnect(AThread: TIdPeerThread);

begin

//ΠŸΠΎΠΏΡ‹Ρ‚Π°Π΅ΠΌΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ

if (AddClient(AThread.Connection)) then

//ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΈΡΠ»Π°Ρ‚ΡŒ своС имя

ProcessMessage(AThread.Connection, AThread.Connection.ReadLn)

else

begin

//НСт мСста для Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ

AThread.Connection.WriteLn(\'error:Достигнуто максимальноС

количСство \' + \'ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ. Π˜Π·Π²ΠΈΠ½ΠΈΡ‚Π΅, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ вас

Π² Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€.\');

AThread.Connection.Socket.Close;

end;

end;

procedure TfrmServer.TCPServerDisconnect(AThread: TIdPeerThread);

var clDisconnected: client; //Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° с ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΎΠ±

//отсоСдинСнном ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅ (Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Ρ‹

//Ρ‚ΠΎΠ»ΡŒΠΊΠΎ поля strName ΠΈ strIP)

begin

//Π£Π΄Π°Π»ΠΈΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± отсоСдинСнном ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅

clDisconnected := DeleteClient(AThread.Connection);

if (clDisconnected.strName <> \'\')then

begin

//Π‘ΠΎΠΎΠ±Ρ‰ΠΈΠΌ ΠΎ событии ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ

SendAll(\'deluser:\' + clDisconnected.strName);

SendAll(\'Нас ΠΏΠΎΠΊΠΈΠ½ΡƒΠ» Β«\' + clDisconnected.strName + \'Β».’);

//Π”ΠΎΠ±Π°Π²ΠΈΠΌ событиС Π² ΠΆΡƒΡ€Π½Π°Π»

if (REPORT) then AddEvent(\'ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΠ»ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ "\' +

clDisconnected.strName + \'" Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅ "\' +

clDisconnected.strIP + \'"\');

end;

end;

procedure TfrmServer.FormCreate(Sender: TObject);

begin

//Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΡΠ΅ΠΊΡ†ΠΈΡŽ

section := TCriticalSection.Create;

end;

ΠŸΠ΅Ρ€Π²Π°Ρ ΠΈ послСдняя ΠΈΠ· ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Π² листингС 11.9 ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ нСпосрСдствСнного ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΊ Ρ€Π°Π±ΠΎΡ‚Π΅ TCP-сСрвСра. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Tf rmServer. TimerlTimer вызываСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ срабатывании Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° Timer 1. Π’ Π½Π΅ΠΉ, исходя ΠΈΠ· Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ значСния глобальной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ SERVERVISIBLE, происходит (ΠΈΠ»ΠΈ Π½Π΅ происходит) скрытиС ΠΎΠΊΠ½Π° сСрвСра. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ глобальной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ SERVERVISIBLE (ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ REPORT) опрСдСляСтся Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ запуска сСрвСра.

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Tf rmServer. FormCreate создаСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ синхронизации, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ для прСдотвращСния ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ доступа ΠΊ ΠΎΠ±Ρ‰ΠΈΠΌ Π΄Π°Π½Π½Ρ‹ΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² (вСдь сСрвСр-Ρ‚ΠΎ Ρƒ нас ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ).

ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ нСпосрСдствСнно для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ взаимодСйствия сСрвСра с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ. Как Π±Ρ‹Π»ΠΎ сказано Ρ€Π°Π½Π΅Π΅, сСрвСр Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ присоСдинСнных ΠΊ Π½Π΅ΠΌΡƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°Ρ…. Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ΠΌ этой ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ являСтся массив структур (ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСн Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΈΠΆΠ΅). Π—Π΄Π΅ΡΡŒ ΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ присоСдинСнии ΠΊ сСрвСру Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° (ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Tf rmServer. TCPServerConnect) прСдпринимаСтся ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° Π½Π°ΠΉΡ‚ΠΈ для ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Π½ΠΎΠ²ΠΎΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ мСсто Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ массивС (Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΡˆΠ€^БНСп^. Если мСсто нашлось, Ρ‚ΠΎ функция AddClient Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ True, ΠΈ сСрвСр ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ€Π΅ΠΆΠΈΠΌ рСгистрации ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Для рСгистрации клиСнтская ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ сСрвСру имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (сообщСниС с прСфиксом name:).

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ сСрвСра Π½Π° ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ клиСнтской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Tf rmServer. TCPServerDisconnect) являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ, ΠΏΠΎΠΌΠΈΠΌΠΎ удалСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± ΠΎΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΠ²ΡˆΠ΅ΠΌΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅ (Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ DeleteClient), всС ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡŽΡ‚ΡΡ ΠΎΠ± отсоСдинСнии собСсСдника (Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SendAll).

ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сообщСния ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° (ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Tf rmServer. Execute) происходит всСго лишь ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ строки Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ProcessMessage, которая ΠΈ занимаСтся Π°Π½Π°Π»ΠΈΠ·ΠΎΠΌ тСкста сообщСния ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ дСйствий, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ рассмотрим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ прямо ΠΈΠ»ΠΈ косвСнно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ описанными Π²Ρ‹ΡˆΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌΠΈ событий ΠΈ Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΠΎ большСй части ΠΈ основываСтся Ρ€Π°Π±ΠΎΡ‚Π° сСрвСрного прилоТСния. Π§Π°ΡΡ‚ΡŒ Ρ„Π°ΠΉΠ»Π° Unitl.pas, содСрТащая объявлСниС Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ (Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½Ρ‹ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 11.10.

...

Листинг 11.10.

Π’ΠΈΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ сСрвСрного прилоТСния (Unitl.pas)

unit Unit1;

interface

uses

…, SyncObjs;

type

TfrmServer = class(TForm)

lstEvents: TListBox; //Бписок событий

…

end;

var

frmServer: TfrmServer;

REPORT: Boolean; //Если = True, Ρ‚ΠΎ всС события

//Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² ListBox

//ΠΎΠΊΠ½Π° сСрвСра

SERVERVISIBLE: Boolean; //Если = True, Ρ‚ΠΎ ΠΎΠΊΠ½ΠΎ показываСтся

//Π½Π° экранС ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΅ΡΡ‚ΡŒ

//Π½Π° ПанСли Π·Π°Π΄Π°Ρ‡

implementation

//Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ структура ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для хранСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ

//ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅ΠΌΡΡ ΠΊ сСрвСру

type

client = record

fUsed: Boolean; {Π―Ρ‡Π΅ΠΉΠΊΠ° занята}

fNamed: Boolean; {ΠšΠ»ΠΈΠ΅Π½Ρ‚ сообщил своС имя}

strName: string; {Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ}

strIP: string; {IP-адрСс ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°}

Connection: TIdTCPServerConnection; {Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

с сСрвСром}

end;

const

MAX_CLIENT = 100;//МаксимальноС количСство ΠΊΠ½ΠΈΠ΅Π½Ρ‚ΠΎΠ²

var

clients: array [1..MAX_CLIENT] of client;//Массив со свСдСниями ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°Ρ…

section: TCriticalSection; //ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ сСкция для синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰Π°Ρ событиС Π² ΠΆΡƒΡ€Π½Π°Π» (ListBox Π½Π° Ρ„ΠΎΡ€ΠΌΠ΅ сСрвСра), ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 11.11.

...

Листинг 11.11.

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ события Π² ΠΆΡƒΡ€Π½Π°Π» сСрвСра

procedure AddEvent(strEvent: string);

begin

section.Enter;

frmServer.lstEvents.Items.Append(strEvent);

section.Leave;

end;

Π’ листингС 11.12 приводится ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, Ρ€Π°ΡΡΡ‹Π»Π°ΡŽΡ‰Π°Ρ тСкстовоС сообщСниС всСм присоСдинСнным ΠΊ сСрвСру ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ.

...

Листинг 11.12.

Рассылка сообщСния всСм ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ

procedure SendAll(strMessage: string);

var

i: Integer;

begin

for i:=1 to MAX_CLIENT do

if (clients[i].fNamed)then

begin

try

clients[i].Connection.WriteLn(strMessage);

except

//ΠŸΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌ рассылку

ErrorCloseConnection(clients[i].Connection);

end;

end;

end;

Π”Π°Π»Π΅Π΅, Π² листингС 11.13, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, ΠΏΠΎΡΡ‹Π»Π°ΡŽΡ‰Π°Ρ тСкстовоС сообщСниС strMessage ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ strName.

...

Листинг 11.13.

ΠŸΠΎΡΡ‹Π»ΠΊΠ° сообщСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ

procedure SendTo(strMessage: string; strName: string);

var

i: Integer;

begin

for i:=1 to MAX_CLIENT do

if (clients[i].fNamed)then

if (clients[i].strName = strName) then

//Нашли ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ

try

clients[i].Connection.WriteLn(strMessage);

except

//ΠŸΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌ рассылку

ErrorCloseConnection(clients[i].Connection);

end;

end;

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, привСдСнная Π² листингС 11.14, Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‡Π°Π΅Ρ‚ ΠΊΠ°ΠΊ Π·Π°Π½ΡΡ‚ΡƒΡŽ для Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ запись Π² массивС clients. Если свободных записСй Π² массивС Π½Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ, Ρ‚ΠΎ достигнуто максимальноС количСство ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.

...

Листинг 11.14.

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Π½ΠΎΠ²ΠΎΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅

function AddClient(Connection: TIdTCPServerConnection): Boolean;

var

i: Integer;

begin

section.Enter;

for i:=1 to MAX_CLIENT do

begin

if (not clients[i].fUsed) then

begin

//Нашли ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡƒΡŽ запись – Π·Π°ΠΏΠΎΠ»Π½ΠΈΠΌ Π΅Π΅

//(ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠΊΠ° бСзымянный)

clients[i].fUsed := True;

clients[i].Connection := Connection;

clients[i].strIP := Connection.Socket.Binding.PeerIP;

AddClient := True;

section.Leave;

Exit;

end;

end;

section.Leave;

AddClient := False;

end;

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° DeleteClient, привСдСнная Π² листингС 11.15, освобоТдаСт запись Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² массивС clients.

...

Листинг 11.15. Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅

function DeleteClient(Connection: TIdTCPServerConnection):client;

var

i: Integer;

begin

section.Enter;

for i:=1 to MAX_CLIENT do

if (clients[i].fUsed) then

if (clients[i].Connection = Connection) then

begin

//Π’ΠΎΡ‚ ΠΎΠ½Π° – запись ΠΎ Π½ΡƒΠΆΠ½ΠΎΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅

clients[i].fUsed := False;

clients[i].fNamed := False;

clients[i].Connection := Nil;

DeleteClient := clients[i];

clients[i].strName := \'\

clients[i].strIP := \'\

section.Leave;

Exit;

end;

end;

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° SendClientList, привСдСнная Π² листингС 11.16, отправляСт клиСнтской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Π²ΡˆΠ΅Π³ΠΎΡΡ) сообщСния addclient: с ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ зарСгистрированного Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

...

Листинг 11.16.

ΠŸΠΎΡΡ‹Π»ΠΊΠ° списка всСх присоСдинСнных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²

procedure SendClientList(Connection: TIdTCPServerConnection);

var

i: Integer;

begin

for i:= 1 to MAX_CLIENT do

if (clients[i].fNamed) then

if (clients[i].Connection <> Connection) then

try

//Π‘ΠΎΠΎΠ±Ρ‰ΠΈΠΌ имя ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ Π½Π°ΠΉΠ΄Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ

Connection.WriteLn(\'adduser:\' + clients[i].strName);

except

//ΠŸΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌ рассылку

ErrorCloseConnection(clients[i].Connection);

end;

end;

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° ErrorCloseConnection (листинг 11.17) вызываСтся ΠΏΡ€ΠΈ ошибкС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ сообщСний ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΈ сСтСвого соСдинСния). Она ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, соСдинСниС с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с ошибками, ΠΈ сообщаСт ΠΎΠ± этом Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ.

...

Листинг 11.17.

Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ соСдинСния с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ (ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки)

procedure ErrorCloseConnection(Connection: TIdTCPServerConnection);

var

clError: client; //Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, соСдинСниС

//с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΡ€Π΅Ρ€Π²Π°Π»ΠΎΡΡŒ (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ имя ΠΈ IP)

begin

//ΠžΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠΌ соСдинСниС, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π΅ с ошибками

clError := DeleteClient(Connection);

//Π‘ΠΎΠΎΠ±Ρ‰ΠΈΠΌ ΠΎΠ± ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ

SendAll(\'deluser:\' + clError.strName);

SendAll(\'Нас ΠΏΠΎΠΊΠΈΠ½ΡƒΠ» Β«\' + clError.strName + \'Β».’);

//Π”ΠΎΠ±Π°Π²ΠΈΠΌ событиС Π² ΠΆΡƒΡ€Π½Π°Π»

if (REPORT) then AddEvent(\'Из-Π·Π° ошибки отсоСдинСн ΠΊΠ»ΠΈΠ΅Π½Ρ‚ "\' +

clError.strName + \'" Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅ Β«\' + clError.strIP + \'Β»\');

end;

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° RegisterClient, привСдСнная Π² листингС 11.18, рСгистрируСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΏΠΎΠ΄ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ Π² сообщСнии name: ΠΈΠΌΠ΅Π½Π΅ΠΌ (Ρ€Π°Π½Π΅Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»Π°ΡΡŒ функция AddClient, которая нашла для записи этого ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ мСсто Π² MaccHBeclients). Если имя, ΠΏΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Ρ…ΠΎΡ‡Π΅Ρ‚ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ, ΡƒΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, Ρ‚ΠΎ клиСнтской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ посылаСтся ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅, послС Ρ‡Π΅Π³ΠΎ соСдинСниС разрываСтся.

...

Листинг 11.18.

РСгистрация Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

procedure RegisterClient(Connection: TIdTCPServerConnection;