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

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

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

ΠŸΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° FIONBIO ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ arg рассматриваСтся ΠΊΠ°ΠΊ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ. Если Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, сокСт Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½ Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ, Ссли Π½Π΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ β€” Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ пСрСвСсти ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сокСт s Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ, Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ дСйствия (листинг 2.28).

Листинг 2.28. ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ сокСта Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ

var

 S: TSocket;

 Arg: u_long;

begin

 ...

 Arg := 1;

 ioctlsocket(S, FIONBIO, Arg);

Пока ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ стандартныС сокСты (Π° Π½Π΅ сокСты Windows), сокСт ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½ Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΈΠ»ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚. ΠΠ΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлан любой сокСт (сСрвСрный ΠΈΠ»ΠΈ клиСнтский) нСзависимо ΠΎΡ‚ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°.

Ѐункция ioctlsocket Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² случаС успСха ΠΈ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ β€” ΠΏΡ€ΠΈ ошибкС. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΊΠ°ΠΊ всСгда, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° для краткости ΠΎΠΏΡƒΡ‰Π΅Π½Π°.

Π˜Ρ‚Π°ΠΊ, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ сокСт Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅. Π‘ особСнностями Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ accept, connect, recv ΠΈ send Π² этом Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΌΡ‹ ΡƒΠΆΠ΅ познакомились. Π’Π΅ΠΏΠ΅Ρ€ΡŒ рассмотрим Ρ‚ΠΎ, ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ Π²Π΅Π΄ΡƒΡ‚ сСбя Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅. Для этого сначала вспомним, ΠΊΠΎΠ³Π΄Π° эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ Π²Ρ‹Π·Π²Π°Π²ΡˆΡƒΡŽ ΠΈΡ… Π½ΠΈΡ‚ΡŒ.

β–‘ accept β€” Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΈΡ‚ΡŒ, Ссли Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π΅Π΅ Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ пуста. 

β–‘ connect β€” Π² случаС TCP Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ сокСт практичСски всСгда, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ трСбуСтся врСмя Π½Π° установлСниС связи с ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΌ сокСтом. Π‘Π΅Π· блокирования Π²Ρ‹Π·ΠΎΠ² connect выполняСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли какая-Π»ΠΈΠ±ΠΎ ошибка Π½Π΅ Π΄Π°Π΅Ρ‚ возмоТности ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΠΊ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ установлСния связи. Π’Π°ΠΊΠΆΠ΅ Π±Π΅Π· блокирования функция connect выполняСтся ΠΏΡ€ΠΈ использовании UDP, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΎΠ½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ устанавливаСт Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ для адрСсов.

β–‘ recv β€” Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΈΡ‚ΡŒ, Ссли Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π±ΡƒΡ„Π΅Ρ€ сокСта пуст.

β–‘ send β€” Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π½ΠΈΡ‚ΡŒ, Ссли Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта нСдостаточно мСста, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΡƒΠ΄Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ.

Если условия, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π±Π΅Π· блокирования, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹, Ρ‚ΠΎ ΠΈΡ… ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ ΠΈ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ°Ρ… ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½ΠΎ. Если ΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π΅Π· блокирования Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π½Π° ΠΎΡˆΠΈΠ±ΠΊΡƒ . Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° Π»ΠΈ ошибка ΠΈΠ·-Π·Π° нСобходимости блокирования ΠΈΠ»ΠΈ ΠΈΠ·-Π·Π° Ρ‡Π΅Π³ΠΎ-Π»ΠΈΠ±ΠΎ Π΅Ρ‰Π΅. ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ WSAGetLastError. Если ΠΎΠ½Π° Π²Π΅Ρ€Π½Π΅Ρ‚ WSAEWOULDBLOCK, Π·Π½Π°Ρ‡ΠΈΡ‚, Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ошибки Π½Π΅ Π±Ρ‹Π»ΠΎ, Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π΅Π· блокирования Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π—Π°ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ сокСт ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ послС WSAEWOULDBLOCK, разумССтся, Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ, Ρ‚.ΠΊ. ошибки Π½Π΅ Π±Ρ‹Π»ΠΎ, ΠΈ связь (Π² случаС TCP) ΠΎΡΡ‚Π°Π»Π°ΡΡŒ Π½Π΅Ρ€Π°Π·ΠΎΡ€Π²Π°Π½Π½ΠΎΠΉ.

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Π½ΡƒΠ»Π΅Π²ΠΎΠΌ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ сокСта (Ρ‚.Π΅. ΠΊΠΎΠ³Π΄Π° функция send пСрСдаст Π΄Π°Π½Π½Ρ‹Π΅ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Π² ΡΠ΅Ρ‚ΡŒ) ΠΈ большом объСмС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ функция send ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ достаточно Π΄ΠΎΠ»Π³ΠΎ, Ρ‚.ΠΊ. эти Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ΡΡ ΠΏΠΎ частям, ΠΈ Π½Π° ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° TCP ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ΡΡ подтвСрТдСния. Но эта Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° Π½Π΅ считаСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, ΠΈ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС send Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ вСсти сСбя с Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΈ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ сокСтами, Ρ‚.Π΅. Π²Π΅Ρ€Π½Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ лишь послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ всС Π΄Π°Π½Π½Ρ‹Π΅ окаТутся Π² сСти.

Для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ accept, recv ΠΈ send WSAEWOULDBLOCK ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ слСдуСт ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ врСмя, ΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π°Π· ΠΎΠ½Π° Π½Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ блокирования ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π°. Ѐункция connect Π² этом случаС Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Ρ„ΠΎΠ½ΠΎΠ²ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡŽ соСдинСния. О Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ этой Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΡΡƒΠ΄ΠΈΡ‚ΡŒ ΠΏΠΎ готовности сокСта, которая провСряСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select. Листинг 2.29 ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ это.

Листинг 2.29. УстановлСниС связи ΠΏΡ€ΠΈ использовании Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ сокСта

var

 S: TSocket;

 Block: u_long;

 SetW, SetE: TFDSet;

begin

 S :=socket(AF_INET, SOCK_STREAM, 0);

 ...

 Block := 1;

 ioctlsocket(S, FIONBIO, Block);

 connect(S, ...);

 if WSAGetLastError <> WSAEWOULDBLOCK then

 begin

  // ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка

  raise ...

 end;

 FD_ZERO(SetW);

 FD_SET(S, SetW);

 FD_ZERO(SetE);

 FD_SET(S, SetE);

 select(0, nil, @SetW, @SetE, nil);

 if FD_ISSET(S, SetW) then

  // Connect Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ

 else if FD_ISSET(S, SetE) then

  // Π‘ΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ

 else

  // ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° Π΅Ρ‰Π΅ какая-Ρ‚ΠΎ ошибка

Напомним, Ρ‡Ρ‚ΠΎ сокСт, входящий Π² мноТСство SetW, Π±ΡƒΠ΄Π΅Ρ‚ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒΡΡ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΌ, Ссли ΠΎΠ½ соСдинСн, Π° Π² Π΅Π³ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ Π΅ΡΡ‚ΡŒ мСсто. Π‘ΠΎΠΊΠ΅Ρ‚, входящий Π² мноТСство SetE, Π±ΡƒΠ΄Π΅Ρ‚ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒΡΡ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΌ, Ссли ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° соСдинСния Π½Π΅ ΡƒΠ΄Π°Π»Π°ΡΡŒ. Π”ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° соСдинСния Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»Π°ΡΡŒ (успСхом ΠΈΠ»ΠΈ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ΠΉ), Π½ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ· этих условий готовности Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π² Π΄Π°Π½Π½ΠΎΠΌ случаС select Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° соСдинСния, ΠΈ ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°Ρ… этой ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡΡƒΠ΄ΠΈΡ‚ΡŒ ΠΏΠΎ Ρ‚ΠΎΠΌΡƒ, Π² ΠΊΠ°ΠΊΠΎΠ΅ ΠΈΠ· мноТСств Π²Ρ…ΠΎΠ΄ΠΈΡ‚ сокСт.

Из ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π΅ Π²ΠΈΠ΄Π½ΠΎ, ΠΊΠ°ΠΊΠΈΠ΅ прСимущСства Π΄Π°Π΅Ρ‚ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ сокСт ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ. Казалось Π±Ρ‹, ΠΏΡ€ΠΎΡ‰Π΅ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ connect Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅, Π΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΈ лишь ΠΏΠΎΡ‚ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ΡŒ сокСт Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ. Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях это Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅. ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π° соСдинСния Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅ связаны с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌΠΈ connect ΠΈ select ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ-Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π° Π² случаС Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ сокСта ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π½ΡƒΠΆΠ΄Π΅Π½Π° сначала Π΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ connect ΠΈ лишь ΠΏΠΎΡ‚ΠΎΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π΅Ρ‰Π΅. 

Ѐункция send для Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ сокСта Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ спСцифичСскиС Ρ‡Π΅Ρ€Ρ‚Ρ‹ повСдСния. Они ΠΏΡ€ΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° свободноС мСсто Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ Π΅ΡΡ‚ΡŒ, Π½ΠΎ Π΅Π³ΠΎ нСдостаточно для хранСния Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° пытаСтся ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π’ этом случаС функция send, согласно Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π±ΡƒΡ„Π΅Ρ€ Ρ‚Π°ΠΊΠΎΠΉ объСм Π΄Π°Π½Π½Ρ‹Ρ…, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚ мСста. ΠŸΡ€ΠΈ этом ΠΎΠ½Π° Π²Π΅Ρ€Π½Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ€Π°Π²Π½ΠΎΠ΅ этому ΠΎΠ±ΡŠΠ΅ΠΌΡƒ (ΠΎΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ мСньшС, Ρ‡Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° len, Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ). ΠžΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅, Π²Ρ‹Π·Π²Π°Π² Π΅Ρ‰Π΅ Ρ€Π°Π· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ send. Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ send Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ использовании TCP. Π’ случаС UDP Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΠ° Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ раздСляСтся Π½Π° части, ΠΈ Ссли Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ Π½Π΅ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚ мСста для всСй Π΄Π΅ΠΉΡ‚Π°Π³Ρ€Π°ΠΌΠΌΡ‹, Ρ‚ΠΎ функция send Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ, a WSAGetLastError β€” WSAEWOULDBLOCK.

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

2.1.16. Π‘Π΅Ρ€Π²Π΅Ρ€ Π½Π° Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… сокСтах

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ создадим сСрвСр, основанный Π½Π° Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… сокСтах. Π­Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ наш ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ сСрвСр, Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ReadFromSocket (см. листинг 2.13). Π­Ρ‚ΠΎΡ‚ сСрвСр (ΠΏΡ€ΠΈΠΌΠ΅Ρ€ NonBlockingServer Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС) состоит ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ Π½ΠΈΡ‚ΠΈ, которая Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ сокСтными опСрациями, Ρ‚.ΠΊ. всС сокСты ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ. На Ρ„ΠΎΡ€ΠΌΠ΅ находится Ρ‚Π°ΠΉΠΌΠ΅Ρ€, ΠΏΠΎ сигналам ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ сСрвСр выполняСт ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ чтСния Π΄Π°Π½Π½Ρ‹Ρ… с сокСтов всСх ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ²ΡˆΠΈΡ…ΡΡ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². Если Π΄Π°Π½Π½Ρ‹Ρ… Π½Π΅Ρ‚, функция recv Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ с ошибкой WSAEWOULDBLOCK, ΠΈ сСрвСр ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ чтСния ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ сокСта.

Запуск сСрвСра (листинг 2.30) ΠΌΠ°Π»ΠΎ Ρ‡Π΅ΠΌ отличаСтся ΠΎΡ‚ запуска ΠΌΠ½ΠΎΠ³ΠΎΠ½ΠΈΡ‚Π΅Π²ΠΎΠ³ΠΎ сСрвСра (см. листинг 2.19). ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈ вся Ρ€Π°Π·Π½ΠΈΡ†Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ вмСсто запуска "ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰Π΅ΠΉ" Π½ΠΈΡ‚ΠΈ сокСт пСрСводится Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ‚Π°ΠΉΠΌΠ΅Ρ€.

Листинг 2.30. Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ сСрвСра Π½Π° Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… сокСтах

// РСакция Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ "Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ" - запуск сСрвСра

procedure TServerForm.BtnStartServerClick(Sender: TObject);

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',