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

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

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

    GetErrorString, mtError, [mbOK], 0);

   // Π’Π°ΠΊ ΠΊΠ°ΠΊ сокСт Π±Ρ‹Π» ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ создан,

   // Π² случаС ошибки Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ

   closesocket(FSocket);

   FSocket := 0;

   Exit;

  end;

  // Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌ "Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ установлСно"

  OnConnect;

 except

  on EConvertError do

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

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

   MessageDlg('"' + EditPort.Text + '"Π½Π΅ являСтся Ρ†Π΅Π»Ρ‹ΠΌ числом',

    mtError, [mbOK], 0);

  on ERangeError do

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

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

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

    mtError, [mbOK], 0);

 end;

end;

Π’Π΅ΠΏΠ΅Ρ€ΡŒ посмотрим, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Ρ€Π΅Π°Π³ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π° Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ (листинг 2.17). Π‘Π°ΠΌΠ° ΠΏΠΎ сСбС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° β€” Π²Π΅Ρ‰ΡŒ ΠΎΡ‡Π΅Π½ΡŒ простая: Π½ΡƒΠΆΠ½ΠΎ ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ адрСс получатСля ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ send. НСсколько слоТнСС выполняСтся Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ, согласно Π½Π°ΡˆΠ΅ΠΌΡƒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π·Π½Π°Π΅Ρ‚, сколько Π±Π°ΠΉΡ‚ΠΎΠ² ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, ΠΈ Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ встрСтит символ #0.

Листинг 2.17. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ

procedure TSimpleClientForm.BtnSendClick(Sender: TObject);

const

 // Π”Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° сокСта ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ порциями.

 // константа BufStep опрСдСляСт Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ†ΠΈΠΈ

 BufStep = 10;

var

 Str: string

 StrLen, BufStart, Portion: Integer;

 Buf: array of Char;

begin

 Str := EditStringToSend.Text;

 StrLen := Length(Str);

 if StrLen = 0 then

 begin

  MessageDlg('ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π΅ допускаСт ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ пустых строк',

   mtError, [mbOK], 0);

  Exit;

 end;

 // отправляСм сСрвСру Π΄Π»ΠΈΠ½Ρƒ строки

 if send(FSocket, StrLen, SizeOf(StrLen), 0) < 0 then

 begin

  MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… сСрвСру '#13#10 +

   GetErrorString, mtError, [mbOK], 0);

  OnDisconnect;

  Exit;

 end;

 // ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ сСрвСру строку

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

 begin

  MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… сСрвСру: '#13#10 +

   GetErrorString, mtError, [mbOK], 0);

  OnDisconnect;

  Exit;

 end;

 BufStart := 0;

 // Π¦ΠΈΠΊΠ» получСния ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΎΡ‚ сСрвСра

 // Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ посылку, ΠΎΠΊΠ°Π½Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΡƒΡŽΡΡ Π½Π° #0

 repeat

  SetLength(Buf, Length(Buf) + BufStep);

  // Π§ΠΈΡ‚Π°Π΅ΠΌ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΡƒΡŽ ΠΏΠΎΡ€Ρ†ΠΈΡŽ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΎΡ‚ сСрвСра

  Portion := recv(FSocket, Buf(BufStart), BufStep, 0);

  if Portion <= 0 then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΎΡ‚ сСрвСра: '#13#10 +

    GetErrorString, mtError, [mbOK], 0);

   OnDisconnect;

   Exit;

  end;

  // Если порция кончаСтся Π½Π° #0, ΠΎΡ‚Π²Π΅Ρ‚ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ, Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ ΠΈΠ·

  // Ρ†ΠΈΠΊΠ»Π°. Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ использовали ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ нашСго ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ

  // Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ сСрвСру ΠΏΡ€ΠΈΡΡ‹Π»Π°Ρ‚ΡŒ нСсколько строк подряд, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ

  // строка Π±ΡƒΠ΄Π΅Ρ‚ выслана сСрвСром Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС Π½ΠΎΠ²ΠΎΠ³ΠΎ запроса ΠΎΡ‚

  // ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Если Π±Ρ‹ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» допускал ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ сСрвСром Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ…

  // ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² подряд, ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ ΠΏΠΎΡ€Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠ³Π»ΠΎ Π±Ρ‹

  // ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Π½Π°Ρ‡Π°Π»ΠΎ ΠΏΠΎΡ€Ρ†ΠΈΠΈ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΎΠ΄Π½ΠΎΠΉ строкС, ΠΊΠΎΠ½Π΅Ρ† -

  // ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ, Π° ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° строки Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΊΠ°Ρ‚ΡŒ Π³Π΄Π΅-Ρ‚ΠΎ Π² сСрСдинС

  if Buf[BufStart + Portion - 1] = #0 then

  begin

   EditReply.Text := PChar(@Buf[0]);

   Break;

  end;

  Inc(BufStart, BufStep);

 until False;

end;

РСакция Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ совсСм простая: Π½ΡƒΠΆΠ½ΠΎ Ρ€Π°Π·ΠΎΡ€Π²Π°Ρ‚ΡŒ соСдинСниС ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ сокСт (листинг 2.18).

Листинг 2.18. РСакция Π½Π° Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ

procedure TSimpleClientForm.BtnDisconnectClick(Sender: TObject);

begin

 shutdown(FSocket, SD_BOTH);

 closesocket(FSocket);

 OnDisconnect;

end;

ΠžΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌ наши ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈ посмотрим, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ. Пока Ρƒ нас ΠΎΠ΄ΠΈΠ½ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с ΠΎΠ΄Π½ΠΈΠΌ сСрвСром, всС Π²ΠΏΠΎΠ»Π½Π΅ прСдсказуСмо: ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ сообщСния, сСрвСр Π½Π° Π½ΠΈΡ… ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚. ΠŸΠΎΠΏΡ‹Ρ‚Π°Π΅ΠΌΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ, Π½Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ, ΠΈ посмотрим, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚. Π‘Π°ΠΌΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, хотя сСрвСр находится Π² своСм Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌ Ρ†ΠΈΠΊΠ»Π΅ ΠΈ Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ accept, для Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π’ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, для ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° достаточно, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сокСт сСрвСра находился Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ попытаСмся ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ сСрвСру со Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π‘Π°ΠΌΠ° ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π½ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ "зависаСт", Ρ‚.ΠΊ. функция recv Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΈΡ‚ΡŒ Π΄ΠΎ ΠΏΡ€ΠΈΡ…ΠΎΠ΄Π° Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ приходят, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ сСрвСр Π½Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ сообщСния ΠΎΡ‚ этого ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΎΡ‚ сСрвСра, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сСрвСр вСрнулся ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept. ΠœΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ сСрвСр Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ» ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ прислал Π΅ΠΌΡƒ сообщСниС. БоотвСтствСнно, сСрвСр ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π½Π° это сообщСниС, ΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ "отвисаСт" β€” Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ с Π½ΠΈΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ.

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ сСрвСр ΠΈ экспСримСнты с Π½ΠΈΠΌ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ·Π½Π°Π²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹, Π½ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ сСрвСр, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ с нСсколькими ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ этого, сдСлаСм Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ написании UDP-Ρ‡Π°Ρ‚Π°: вынСсСм Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Π½ΠΈΡ‚ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρƒ с Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ функциями (ΠΏΡ€ΠΈΠΌΠ΅Ρ€ MultithreadedServer Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС). Нам понадобится ΠΎΠ΄Π½Π° Π½ΠΈΡ‚ΡŒ для выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept ΠΈ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ Π½ΠΈΡ‚ΠΈ Π½Π° Ρ€Π°Π±ΠΎΡ‚Ρƒ с ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΠΌΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ. Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ выполняСтся ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ (листинг 2.19). ПослС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов, создания сокСта ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° Π΅Π³ΠΎ Π² Ρ€Π΅ΠΆΠΈΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ ΠΎΠ½Π° создаСт Π½ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏΠ° TListenThread, ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Π΅ΠΉ дСскриптор сокСта ΠΈ большС с сокСтами Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ β€” дальнСйшая Ρ€ΠΎΠ»ΡŒ Π³Π»Π°Π²Π½ΠΎΠΉ Π½ΠΈΡ‚ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ сообщСний. Благодаря этому сСрвСр ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ интСрфСйс.

Листинг 2.19. Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΠΌΠ½ΠΎΠ³ΠΎΠ½ΠΈΡ‚Π΅Π²ΠΎΠ³ΠΎ сСрвСра

// РСакция Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ

procedure TServerForm.BtnStartServerClick(Sender: TObject);

var

 // Π‘ΠΎΠΊΠ΅Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ "ΡΠ»ΡƒΡˆΠ°Ρ‚ΡŒ"

 ServerSocket: TSocket;

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

 ServerAddr: TSockAddr;

begin

 // Π€ΠΎΡ€ΠΌΠΈΡ€yΠ΅ΠΌ Π°Π΄Ρ€Π΅Ρ для привязки.

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

 ServerAddr.sin_family := AF_INET;

 ServerAddr.sin_addr.S_addr := ADDR_ANY;

 try

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

  if ServerAddr.sin_port = 0 then

  begin

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

    mtError, [mbOK], 0);

   Exit;

  end;

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

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

  if ServerSocket = INVALID_SOCKET then

  begin

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

    mtError, [mbOK], 0);

   Exit;

  end;

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

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

  begin

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

    GetErrorString, mtError, [mbOK], 0);

   closesocket(ServerSocket);

   Exit;

  end;

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

  if listen(ServerSocket, SOMAXCONN) = SOCKET_ERROR then

  begin

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

    GetErrorString, mtError, [mbOK], 0);

   closesocket(ServerSocket);

   Exit;

  end;

  // Запуск Π½ΠΈΡ‚ΠΈ, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰Π΅ΠΉ ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт

  TListenThread.Create(ServerSocket);

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

  LabelPortNumber.Enabled := False;

  EditΠ ΠΎrtNumber.Enabled := False;

  BtnStartServer.Enabled := False;

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

 except

  on EConvertError do

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

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

   MessageDlg('"' + EditPortNumber.Text + '"Π½Π΅ являСтся Ρ†Π΅Π»Ρ‹ΠΌ числом',

    mtError, [mbOK], 0);

  on ERangeError do

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

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

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

    mtError, [mbOK], 0);