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

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

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

var

 // АдрСс, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ привязываСтся ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт

 ServerAddr: TSockAddr;

 NonBlockingArg: u_long;

begin

 // Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ адрСс для привязки.

 FillChar(ServerAddr.sin_zero, SizeOf(ServerAddr.sin_zero), 0);

 ServerAddr.sin_family := AF_INET;

 ServerAddr.sin_addr.S_addr := INADDR_ANY;

 try

  ServerAddr.sin_port := htons(StrToInt(EditPortNumber.Text));

  if ServerAddr.sin_port = 0 then

  begin

   MessageDlg('НомСр ΠΏΠΎΡ€Ρ‚Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ 1-65535',

    mtError, [mbOK], 0);

   Exit;

  end;

  // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сокСта

  FServerSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if FServerSocket = INVALID_SOCKET then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ создании сокСта: '#13#10 + GetErrorString,

    mtError, [mbOK], 0);

   Exit;

  end;

  // ΠŸΡ€ΠΈΠ²ΡΠ·ΠΊΠ° сокСта ΠΊ адрСсу

  if bind(FServerSocket, ServerAddr, SizeOf(ServerAddr)) = SOCKET_ERROR then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ привязкС сокСта ΠΊ Π°Π΄Ρ€Π΅cΡƒ: '#13#10 +

    GetErrorString, mtError, [mbOK], 0);

   closesocket(FServerSocket);

   Exit;

  end;

  // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ сокСта Π² Ρ€Π΅ΠΆΠΈΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ

  if listen(FServerSocket, SOMAXCONN) = SOCKET_ERROR then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π΅ сокСта Π² Ρ€Π΅ΠΆΠΈΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ:'#13#10 +

    GetErrorString, mtError, [mbOK], 0);

   closesocket(FServerSocket);

   Exit;

  end;

  // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ сокСта Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ

  NonBlockingArg := 1;

  if ioctlsocket(FServerSocket, FIONBIO, NonBlockingArg) = SOCKET_ERROR then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π΅ сокСта Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ:'#13#10 +

    GetErrorString, mtError, [mbOK], 0);

   closesocket(FServerSocket);

   Exit;

  end;

  // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ элСмСнтов управлСния Π² состояниС "Π‘Π΅Ρ€Π²Π΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚"

  LabelPortNumber.Enabled := False;

  EditΠ ΠΎrtNumber.Enabled := False;

  BtnStartServer.Enabled := False;

  TimerRead.Interval := TimerInterval;

  LabelServerState.Caption := 'Π‘Π΅Ρ€Π²Π΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚';

 except

  on EConvertError do

   // Π­Ρ‚ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС -

   // ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ StrToInt(EditPortNumber.Text)

   MessageDlg('"' + EditPortNumber.Text +

    '" Π½Π΅ являСтся Ρ†Π΅Π»Ρ‹ΠΌ числом', mtError, [mbOK], 0);

  on ERangeError do

   // Π­Ρ‚ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС -

   // ΠΏΡ€ΠΈ присваивании значСния Π½ΠΎΠΌΠ΅Ρ€Ρƒ ΠΏΠΎΡ€Ρ‚Π°

   MessageDlg('НомСр ΠΏΠΎΡ€Ρ‚Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ 1-65535',

    mtError, [mbOK], 0);

 end;

end;

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

ВзаимодСйствиС сСрвСра с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ состоит ΠΈΠ· Ρ‚Ρ€Π΅Ρ… этапов. На ΠΏΠ΅Ρ€Π²ΠΎΠΌ этапС сСрвСр ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ…Π±Π°ΠΉΡ‚Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ β€” Π΄Π»ΠΈΠ½Ρƒ строки. На Π²Ρ‚ΠΎΡ€ΠΎΠΌ этапС сСрвСр ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° саму строку, Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡƒΠΆΠ΅ извСстСн ΠΈΠ· Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΌ этапС. На Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΌ этапС сСрвСр отправляСт ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ, состоящий ΠΈΠ· строки, Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰Π΅ΠΉΡΡ Π½ΡƒΠ»Π΅ΠΌ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΌ "Ρ‚ΠΈΠΊΠ΅" Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° сСрвСр ΠΌΠΎΠ³ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ, ΠΏΡ€Π΅Ρ€Π²Π°Π½Π½ΠΎΠ΅ Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΌ мСстС, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ, Π½Π° ΠΊΠ°ΠΊΠΎΠΌ этапС Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ взаимодСйствиС Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ Ρ€Π°Π·, сколько Π±Π°ΠΉΡ‚ΠΎΠ² Π½Π° Π΄Π°Π½Π½ΠΎΠΌ этапС ΡƒΠΆΠ΅ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½ΠΎ ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΈ сколько Π΅Ρ‰Π΅ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ. Для хранСния этих Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ TTransportPhase ΠΈ TConnection (листинг 2.31).

Листинг 2.31. Π’ΠΈΠΏΡ‹ TTransportPhase ΠΈ TConnection 

type

 // Π­Ρ‚Π°ΠΏ взаимодСйствия с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ:

 // tpReceiveLength - сСрвСр ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π΄Π»ΠΈΠ½Ρƒ строки

 // tpReceiveString - сСрвСр ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° строку

 // tpSendString - сСрвСр посылаСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ строку

 TTransportPhase = (tpReceiveLength, tpReceiveString, tpSendString);

 // Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ соСдинСнии с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ:

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

 // ClientAddr - строковоС прСдставлСниС адрСса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 // MsgSize - Π΄Π»ΠΈΠ½Π° строки, получаСмая ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 // Msg - строка, получаСмая ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈΠ»ΠΈ отправляСмая Π΅ΠΌΡƒ,

 // Phase - этап взаимодСйствия с Π΄Π°Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

 // Offset - количСство Π±Π°ΠΉΡ‚ΠΎΠ², ΡƒΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 // ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹Ρ… Π΅ΠΌΡƒ Π½Π° Π΄Π°Π½Π½ΠΎΠΌ этапС

 // BytesLeft - сколько Π±Π°ΠΉΡ‚ΠΎΠ² ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 // ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΅ΠΌΡƒ Π½Π° Π΄Π°Π½Π½ΠΎΠΌ этапС

 PConnection = ^TConnection;

 TConnection = record

  ClientSocket: TSocket;

  ClientAddr: string;

  MsgSize: Integer;

  Msg: string;

  Phase: TTransportPhase;

  Offset: Integer;

  BytesLeft: Integer;

 end;

Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° создаСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ экзСмпляр записи TConnection, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ хранится информация ΠΊΠ°ΠΊ ΠΎ самом ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ, Ρ‚Π°ΠΊ ΠΈ ΠΎ Ρ‚ΠΎΠΌ, Π½Π° ΠΊΠ°ΠΊΠΎΠΌ этапС находится взаимодСйствиС с Π΄Π°Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈ взаимодСйствиС с ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΠΌΠΈΡΡ Ρ€Π°Π½Π΅Π΅ рСализуСтся, ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ сказано, ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ события Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°. Код ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 2.32. 

Листинг 2.32. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°

// ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сообщСния ΠΎΡ‚ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°

// Π’ Ρ…ΠΎΠ΄Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ провСряСтся Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ вновь ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΡ…ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²

// Π° Ρ‚Π°ΠΊΠΆΠ΅ осущСствляСтся ΠΎΠ±ΠΌΠ΅Π½ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ

procedure TServerForm.TimerReadTimer(Sender: TObject);

var

 // Π‘ΠΎΠΊΠ΅Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСтся для вновь ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 ClientSocket: TSocket;

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

 ClientAddr: TSockAddr;

 // Π”Π»ΠΈΠ½Π° адрСса

 AddrLen: Integer;

 // Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ пСрСмСнная для создания Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

 NewConnection: PConnection;

 I: Integer;

begin

 AddrLen := SizeOf(TSockAddr);

 // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ. Π’Π°ΠΊ ΠΊΠ°ΠΊ сокСт Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ,

 // accept Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΈΡ‚ΡŒ Π΄Π°ΠΆΠ΅ Π² случаС отсутствия

 // ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ.

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

 if ClientSocket = INVALID_SOCKET then

 begin

  // Если ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π΄ΡˆΠ°Ρ ошибка - WSAEWOULDBLOCK, это просто ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚,

  // Ρ‡Ρ‚ΠΎ Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π½Π΅Ρ‚, Π° Π²ΠΎΠΎΠ±Ρ‰Π΅ всС Π² порядкС,

  // поэтому ΠΎΡˆΠΈΠ±ΠΊΡƒ WSAEWOULDBLOCK ΠΌΡ‹ просто ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ. ΠŸΡ€ΠΎΡ‡ΠΈΠ΅ ΠΆΠ΅

  // ошибки ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС ΡΠ΅Ρ€ΡŒΠ΅Π·Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ,

  // ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ остановки сСрвСра.

  if WSAGetLastError <> WSAEWOULDBLOCK then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:'#13#10 +

    GetErrorString + #13#10'Π‘Π΅Ρ€Π²Π΅Ρ€ Π±ΡƒΠ΄Π΅Ρ‚ остановлСн', mtError, [mbOK], 0);

   ClearConnections;

   closesocket(FServerSocket);

   OnStopServer;

  end;

 end

 else

 begin

  // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ запись для Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ заполняСм Π΅Π΅

  New(NewConnection);

  NewConnection.ClientSocket := ClientSocket;

  NewConnection.Π‘lientAddr :=

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

    Ord(ClientAddr.sin_addr.S_un_b.s_b1),

    Ord(ClientAddr.sin_addr.S_un_b.s_b2),

    Ord(ClientAddr.sin_addr.S_un_b.s_b3),

    Ord(ClientAddr.sin_addr.S_un_b.s_b4),

    ntohs(ClientAddr.sin_port)]);

  NewConnection.Phase := tpReceiveLength;

  NewConnection.Offset := 0;

  NewConnection.BytesLeft := SizeOf(Integer);

  // ДобавляСм запись Π½ΠΎΠ²ΠΎΠ³ΠΎ соСдинСния Π² список

  FConnections.Add(NewConnection);

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

   NewConnection.ClientAddr);

 end;

 // ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ всС ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ.

 // Π¦ΠΈΠΊΠ» ΠΈΠ΄Π΅Ρ‚ ΠΎΡ‚ ΠΊΠΎΠ½Ρ†Π° списка ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π² Ρ…ΠΎΠ΄Π΅

 // ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ соСдинСниС ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ΄Π°Π»Π΅Π½ΠΎ ΠΈΠ· списка.

 for I := FConnections.Count - 1 downto 0 do processConnection(I);

end;

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ сокСт, созданный Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ accept, Π½ΠΈΠ³Π΄Π΅ Π½Π΅ пСрСводится Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ сокСт наслСдуСт свойства ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ сокСта, поэтому ΠΎΠ½ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС сразу создаСтся Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ.

БобствСнно взаимодСйствиС сСрвСра с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ вынСсСно Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ ProcessConnection (листинг 2.33). ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ осущСствляСт Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ Π΄Π°Π½Π½Ρ‹Ρ… Π² соотвСтствии с этапом, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΠ»ΠΎΡΡŒ взаимодСйствиС. ΠŸΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ просто Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° Ρ‚Π΅ΠΌ, ΠΊΡƒΠ΄Π° ΠΈ сколько Π΄Π°Π½Π½Ρ‹Ρ… Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ.