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

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

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

    'Ошибка ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ WinSock');

  // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сокСта, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Ρ‚Π΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ "ΡΠ»ΡƒΡˆΠ°Ρ‚ΡŒ" ΠΏΠΎΡ€Ρ‚

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

  if MainSocket = INVALID_SOCKET then

   raise ESocketException.Create(

    'НСвозмоТно ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт: ' + GetErrorString');

  // Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ адрСса для "ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ" сокСта

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

  MainSockAddr.sin_family := AF_INET;

  // Π’Ρ‹Π±ΠΎΡ€ IP-адрСса довСряСм систСмС

  MainSockAddr.sin_addr.S_addr := INADDR_ANY;

  // ΠŸΠΎΡ€Ρ‚ Π½Π°Π·Π½Π°Ρ‡Π°Π΅ΠΌ, Π½Π΅ забывая пСрСвСсти Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ€ Π² сСтСвой Ρ„ΠΎΡ€ΠΌΠ°Ρ‚

  MainSockAddr.sin_port := htons(Port);

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

  if bind(MainSocket, MainSockAddr, SizeOf(MainSockAddr)) = SOCKET_ERROR then

   raise ESocketException.Create(

    'НСвозмоТно ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт ΠΊ адрСсу: ' +

    GetErrorString);

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

  if listen(MainSocket, SOMAXCONN) = SOCKET_ERROR then

   raise ESocketException.Create(

    'НСвозмоТно ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ сокСт Π² Ρ€Π΅ΠΆΠΈΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ: ' +

    GetErrorString);

  WriteLn(OemString('Π‘Π΅Ρ€Π²Π΅Ρ€ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π½Π°Ρ‡Π°Π» ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΡ€Ρ‚Π° '), Port);

  ...

  // Основная Ρ‡Π°ΡΡ‚ΡŒ сСрвСра ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 2.15

  ...

 except

  on Π•: ESocketException do

   WriteLn(OemString(E.Message));

  on E: Exception do

   WriteLn(OemString('НСоТиданноС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ' + E.ClassName +

    ' с сообщСниСм ' + E.Message));

 end;

end.

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

Листинг 2.15. Основная Ρ‡Π°ΡΡ‚ΡŒ сСрвСра SimplestServer

// Начало Ρ†ΠΈΠΊΠ»Π° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ общСния с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

repeat

 ClientSockAddrLen := SizeOf(ClientSockAddr);

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

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

 ClientSocket :=

  accept(MainSocket, @ClientSockAddr, @ClientSockAddrLen);

 if ClientSocket = INVALID_SOCKET then

  raise ESocketException.Create(

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

// ΠŸΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ сообщСния Π½Π΅ Π·Π°Π±Ρ‹Π²Π°Π΅ΠΌ,

 // Ρ‡Ρ‚ΠΎ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π° ΠΈΠΌΠ΅Π΅Ρ‚ сСтСвой Ρ„ΠΎΡ€ΠΌΠ°Ρ‚

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

  Ord(ClientSockAddr.sin_addr.S_un_b.s_b1), '.',

  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));

 // Π¦ΠΈΠΊΠ» общСния с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ. ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€,

 // ΠΏΠΎΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π·Π°ΠΊΡ€ΠΎΠ΅Ρ‚ соСдинСниС ΠΈΠ»ΠΈ ΠΏΠΎΠΊΠ°

 // Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ошибка

 repeat

  // Π§ΠΈΡ‚Π°Π΅ΠΌ Π΄Π»ΠΈΠ½Ρƒ присланной ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ строки ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Π΅ Π² StrLen

  case ReadFromSocket(ClientSocket, StrLen, SizeOf(StrLen)) of

  0: begin

   WriteLn(OemString('ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π» соСдинСниС');

   Break;

  end;

  -1: begin

   WriteLn(OemString('Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ',

    GetErrorString));

   Break;

  end;

  end;

  // ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π΅ допускаСт строк Π½ΡƒΠ»Π΅Π²ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹

  if StrLen <= 0 then

  begin

   WriteLn(OemString('НСвСрная Π΄Π»ΠΈΠ½Π° строки ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: '), StrLen);

   Break;

  end;

  // Установка Π΄Π»ΠΈΠ½Ρ‹ строки Π² соотвСтствии с ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ

  SetLength(Str, StrLen);

  // Π§Ρ‚Π΅Π½ΠΈΠ΅ строки Π½ΡƒΠΆΠ½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹

  case ReadFromSocket(ClientSocket, Str[1], StrLen) of

  0: begin

   WriteLn(OemString('ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΊΡ€Ρ‹Π» соСдинСниС'));

   Break;

  end;

  -1: begin

   WriteLn(OemString( 'Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°: ' +

    GetErrorString));

   Break;

  end;

  end;

  WriteLn(OemString('ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π° строка: ' + Str));

  // ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ строки

  Str :=

   AnsiUpperCase(StringReplace(Str, #0, '#0', [rfReplaceAll])) +

    ' (Simplest server)';

  // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° строки. ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ΡΡ Π½Π° ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚ большС, Ρ‡Π΅ΠΌ

  // Π΄Π»ΠΈΠ½Π° строки, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ символ #0 Ρ‚ΠΎΠΆΠ΅ ΠΏΠΎΠΏΠ°Π» Π² ΠΏΠ°ΠΊΠ΅Ρ‚

  if send(ClientSocket, Str[1], Length(Str) + 1, 0) < 0 then

  begin

   WriteLn(OemString('Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ: ' +

    GetErrorString));

   Break;

  end;

  WriteLn(OemString('ΠšΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ ΠΎΡ‚Π²Π΅Ρ‚: ' + Str));

  // Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ†ΠΈΠΊΠ»Π° ΠΎΠ±ΠΌΠ΅Π½Π° с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ

 until False;

 // Π‘ΠΎΠΊΠ΅Ρ‚ для связи с ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ большС Π½Π΅ Π½ΡƒΠΆΠ΅Π½

 closesocket(ClientSocket);

until False;

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ написанию ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ этого ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° находится Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС Π² ΠΏΠ°ΠΏΠΊΠ΅ SimpleClient, Π³Π»Π°Π²Π½ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° рис. 2.4. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Π²ΡˆΡƒΡŽ Π΅Π΅ Π½ΠΈΡ‚ΡŒ, β€” Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ recv. Но ΠΏΠΎ Π½Π°ΡˆΠ΅ΠΌΡƒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ сСрвСр Π½Π΅ посылаСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΏΠΎ собствСнной ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ‚ΠΈΠ²Π΅, ΠΎΠ½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π½Π° сообщСния ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ всСгда Π³ΠΎΡ‚ΠΎΠ² ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ сообщСниС, ΠΎΠ½ Π΅Π³ΠΎ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ своСго. Π’ простых случаях, ΠΊΠΎΠ³Π΄Π° сообщСниС ΠΈΠΌΠ΅Π΅Ρ‚ нСбольшой Ρ€Π°Π·ΠΌΠ΅Ρ€, Π° Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡ‚Π²Π΅Ρ‚Π° Π½Π° сСрвСрС Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° получСния ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΎΡ‚ сСрвСра сразу ΠΆΠ΅ послС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π΅ΠΌΡƒ сообщСния Π² ΠΏΠΎΠ΄Π°Π²Π»ΡΡŽΡ‰Π΅ΠΌ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ случаСв Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π° ΠΎΡΡ‚Π°Π²ΡˆΠ΅Π΅ΡΡ Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ количСство случаСв считаСм форс-ΠΌΠ°ΠΆΠΎΡ€ΠΎΠΌ ΠΈ допускаСм, Ρ‡Ρ‚ΠΎ Π² Ρ‚Π°ΠΊΠΎΠΉ ситуации Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ допустимо. На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ° Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ это Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° сСрвСр Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ Π½Π° сообщСния ΠΈΠ»ΠΈ связь с Π½ΠΈΠΌ Π±ΡƒΠ΄Π΅Ρ‚ потСряна. Для простого ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° с нСвысокими трСбованиями ΠΊ надСТности Ρ‚Π°ΠΊΠΎΠ΅ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ допустимо ΠΈ Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использовано Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅. А Π² дальнСйшСм ΠΌΡ‹ познакомимся со срСдствами Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΌΠΈ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π°Π±ΠΎΡ‚Π° с сокСтами Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅.

Рис. 2.4. Π“Π»Π°Π²Π½ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ SimpleClient


Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, наш ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‡Π΅Π½ΡŒ простым: ΠΏΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π‘ΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΅Π΄ΠΈΠ½ΡΡ‚ΡŒΡΡ с сСрвСром, ΠΏΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ΅ ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ β€” ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ сСрвСру сообщСниС ΠΈ Π΄ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒΡΡ ΠΎΡ‚Π²Π΅Ρ‚Π°. Π’Ρ€Π΅Ρ‚ΡŒΡ ΠΊΠ½ΠΎΠΏΠΊΠ°, ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ, слуТит для ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сСрвСром. Рассмотрим эти дСйствия ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅.

ΠŸΡ€ΠΈ соСдинСнии с сСрвСром ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ сокСт ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ connect. Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ сокСт ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΈ ΠΏΠΎΡ‚ΠΎΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈΠΌ Π½Π° протяТСнии всСго Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ‚.ΠΊ. послС закрытия соСдинСния (Π½Π΅Π²Π°ΠΆΠ½ΠΎ, ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ ΠΈΠ·-Π·Π° ошибки) сокСт большС нСльзя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΏΡ€ΠΈ установлСнии соСдинСния ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· приходится ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ сокСт. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ Π‘ΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 2.16.

Листинг 2.16. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ Π‘ΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ

procedure TSimpleClientForm.BtnConnectClick(Sender: TObject);

var

 // АдрСс сСрвСра

 ServerAddr: TSockAddr;

begin

 // Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ адрСс сСрвСра, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ

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

 ServerAddr.sin_family := AF_INET;

 ServerAddr.sin_addr.S_addr := inet_addr(PChar(EditIPAddress.Text));

 // Для совмСстимости со старыми вСрсиями Delphi ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠΌ

 // константу INADDR_ANY ΠΊ Ρ‚ΠΈΠΏΡƒ u_long

 if ServerAddr.sin_addr.S_addr := u_long(INADDR_NONE)then

 begin

  MessageDlg('БинтаксичСская ошибка Π² IΠ -адрСсС', mtError, [mbOK], 0);

  Exit;

 end;

 try

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

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

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

  if FSocket = INVALID_SOCKET then

  begin

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

    GetErrorString, mtError, [mbOK], 0);

   Exit;

  end;

  // ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ сСрвСру

  if connect(FSocket, ServerAddr, SizeOf(ServerAddr)) < 0 then

  begin

   MessageDlg('Ошибка ΠΏΡ€ΠΈ установлСнии ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ: '#13#10 +