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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «БистСмноС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² срСдС WindowsΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 98

Автор ДТонсон Π₯Π°Ρ€Ρ‚

Π˜ΠΌΠ΅ΡŽΡ‚ΡΡ Ρ‚Π°ΠΊΠΆΠ΅ различия Π² модСлях программирования сСрвСра ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ сСрвСров ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ² ΠΈ сокСтов

Установка соСдинСния с нСсколькими ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΏΡ€ΠΈ использовании сокСтов Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ выполнСния ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠΉ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ сокСт. По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ ΠΊΠ°Π½Π°Π»Π°ΠΌΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ отличия:

β€’ Π’ случаС ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ² трСбуСтся, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ экзСмпляр ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° ΠΈ дСскриптор Ρ‚ΠΈΠΏΠ° HANDLE создавались с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ CreateNamedPipe, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ для создания экзСмпляров сокСтов примСняСтся функция accept.

β€’ Π”опустимоС количСство клиСнтских сокСтов Π½ΠΈΡ‡Π΅ΠΌ Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ (функция listen ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ лишь количСство ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌΡ‹Ρ… Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ), Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ количСство экзСмпляров ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ², Π² зависимости ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ ΡƒΠΊΠ°Π·Π°Π½ΠΎ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ CreateNamedPipe, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹ΠΌ.

β€’ ΠΠ΅ сущСствуСт Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сокСтами, Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ TransactNamedPipe.

β€’ Π˜ΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΊΠ°Π½Π°Π»Ρ‹ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΠΎΡ€Ρ‚ΠΎΠ² с явно Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π½ΠΎΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ ΠΏΠΎ ΠΈΠΌΠ΅Π½Π°ΠΌ. 

Π’ случаС сСрвСра ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ² ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½ΠΎΠ³ΠΎ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ дСскриптора Ρ‚ΠΈΠΏΠ° HANDLE Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° Π΄Π²ΡƒΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (CreateNamedPipe ΠΈ ConnectNamedPipe), Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ сСрвСр сокСта Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (socket, bind, listen ΠΈ accept).

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ² ΠΈ сокСтов

Π’ случаС ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ² Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ WaitNamedPipe ΠΈ CreateFile. Если ΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ сокСты, этот порядок Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² обращаСтся, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ функция socket создаСт сокСт, Π° функция connect β€” Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚.

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ функция connect являСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° сокСта, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ функция ConnectNamedPipe ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ сСрвСром ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: функция ΠΏΡ€ΠΈΠ΅ΠΌΠ° сообщСний Π² случаС сокСта

Часто оказываСтся ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ сообщСния Π² Π²ΠΈΠ΄Π΅ Π΅Π΄ΠΈΠ½Ρ‹Ρ… Π±Π»ΠΎΠΊΠΎΠ². Как Π±Ρ‹Π»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² Π³Π»Π°Π²Π΅ 11, ΠΊΠ°Π½Π°Π»Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ. Однако Π² случаС сокСтов трСбуСтся созданиС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°, содСрТащСго Ρ€Π°Π·ΠΌΠ΅Ρ€ сообщСния, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ слСдуСт само сообщСниС. Для ΠΏΡ€ΠΈΠ΅ΠΌΠ° Ρ‚Π°ΠΊΠΈΡ… сообщСний ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° функция ReceiveMessage, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…. Π’ΠΎ ΠΆΠ΅ самоС ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈ ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SendMessage, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠΉ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ сообщСний.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ сообщСниС принимаСтся Π² Π²ΠΈΠ΄Π΅ Π΄Π²ΡƒΡ… частСй: Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΈ содСрТимого. НиТС ΠΌΡ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ MESSAGE соотвСтствуСт 4-Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ. Но Π΄Π°ΠΆΠ΅ для 4-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Π΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ recv, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΠΎΠ»Π½ΠΎΠ΅ считываниС, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ функция recv Π½Π΅ являСтся Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΠΎΠΉ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅, относящССся ΠΊ Win64

Π’ качСствС Ρ‚ΠΈΠΏΠ° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… для хранСния Ρ€Π°Π·ΠΌΠ΅Ρ€Π° сообщСния, Π²Ρ‹Π±Ρ€Π°Π½ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… фиксированной точности LONG32, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΏΠΎΠ»Π½Π΅ достаточно для размСщСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Π² сообщСния ΠΏΡ€ΠΈ взаимодСйствии с систСмами, ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΎΡ‚ Windows, ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ годится для Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ пСрСкомпиляции ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ для Π΅Π΅ использования Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅ Win64 (см. Π³Π»Π°Π²Ρƒ 16).

DWORD ReceiveMessage (MESSAGE *pMsg, SOCKET sd) {

 /* Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ состоит ΠΈΠ· 4-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ поля Ρ€Π°Π·ΠΌΠ΅Ρ€Π° сообщСния, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ слСдуСт собствСнно содСрТимоС. */ 

 DWORD Disconnect = 0;

 LONG32 nRemainRecv, nXfer;

 LPBYTE pBuffer;

 /* Π‘Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ сообщСниС. */

 /* Π‘Π½Π°Ρ‡Π°Π»Π° считываСтся Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, Π° Π·Π°Ρ‚Π΅ΠΌ содСрТимоС. */

 nRemainRecv = 4; /* Π Π°Π·ΠΌΠ΅Ρ€ поля Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°. */

 pBuffer = (LPBYTE)pMsg; /* recv ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ всС Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Ρ‹Π΅ Π±Π°ΠΉΡ‚Ρ‹. */

 while (nRemainRecv > 0 && !Disconnect) {

  nXfer = recv(sd, pBuffer, nRemainRecv, 0);

  Disconnect = (nXfer == 0);

  nRemainRecv –=nXfer;

  pBuffer += nXfer;

 }

 /* Π‘Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ содСрТимоС сообщСния. */

 nRemainRecv = pMsg->RqLen;

 while (nRemainRecv > 0 && !Disconnect) {

  nXfer = recv(sd, pBuffer, nRemainRecv, 0);

  Disconnect = (nXfer == 0);

  nRemainRecv –=nXfer;

  pBuffer += nXfer;

 }

 return Disconnect;

}

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° основС сокСта

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° 12.1 прСдставляСт собой ΠΏΠ΅Ρ€Π΅Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ клиСнтской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ clientNP (ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° 11.2), которая использовалась Π² случаС ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°Π½Π°Π»ΠΎΠ². ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ осущСствляСтся самым нСпосрСдствСнным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ лишь Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… пояснСний.

β€’ Π’мСсто обнаруТСния сСрвСра с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠΎΡ‡Ρ‚ΠΎΠ²Ρ‹Ρ… ящиков ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π²Π²ΠΎΠ΄ΠΈΡ‚ IP-адрСс сСрвСра Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкС. Если IP-адрСс Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ адрСс 127.0.0.1, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ локальной систСмС.

β€’ Π”ля ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΈ ΠΏΡ€ΠΈΠ΅ΠΌΠ° сообщСний ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ReceiveMessage, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ здСсь Π½Π΅ прСдставлСны.

β€’ ΠΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ€Ρ‚Π°, SERVER_PORT, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ClntSrvr.h.

Π₯отя ΠΊΠΎΠ΄ написан для выполнСния ΠΏΠΎΠ΄ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Windows, СдинствСнная Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ Windows связана с использованиСм Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… прСфикс WSA.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° 12.1. clientSK: ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° основС сокСтов 

/* Π“Π»Π°Π²Π° 12. clientSK.с */

/* ΠžΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки. */

/* Π’Π•Π Π‘Π˜Π― НА ΠžΠ‘ΠΠžΠ’Π• WINDOWS SOCKETS. */

/* Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄ для пСрСсылки сСрвСрному процСссу*/

/* Ρ‡Π΅Ρ€Π΅Π· соСдинСниС с сокСтом. ДоТидаСтся ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ Π΅Π³ΠΎ. */


#define _NOEXCLUSIONS /* ВрСбуСтся для Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ сокСта. */

#include "EvryThng.h"

#include "ClntSrvr.h" /* ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ структуры записСй запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π°. */


/* Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ сообщСния для обслуТивания запросов ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ². */

/* ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ReceiveResponseMessage ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ сообщСния. */

static DWORD SendRequestMessage(REQUEST *, SOCKET);

static DWORD ReceiveResponseMessage(RESPONSE *, SOCKET);

struct sockaddr_in ClientSAddr; /* АдрСс сокСта ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. */

int _tmain(DWORD argc, LPTSTR argv[]) {

 SOCKET ClientSock = INVALID_SOCKET;

 REQUEST Request; /* Π‘ΠΌ. ClntSrvr.h. */

 RESPONSE Response; /* Π‘ΠΌ. ClntSrvr.h. */

 WSADATA WSStartData; /* Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСта. */

 BOOL Quit = FALSE;

 DWORD ConVal, j;

 TCHAR PromptMsg[] = _T("\nΠ’Π²Π΅Π΄ΠΈΡ‚Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ> ");

 TCHAR Req[MAX_RQRS_LEN];

 TCHAR QuitMsg[] = _T("$Quit");

 /* Запрос: Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. */

 TCHAR ShutMsg[] = _T("$ShutDownServer"); /* ΠžΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ. */

 CHAR DefaultIPAddr[] = "127.0.0.1"; /* Π›ΠΎΠΊΠ°Π»ΡŒΠ½Π°Ρ систСма. */

 /* Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ WSA; Π·Π°Π΄Π°Π½Π° вСрсия 2.0, Π½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈ вСрсия 1.1. */

 WSAStartup(MAKEWORD(2, 0), &WSStartData);

 /* ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ ΠΊ сСрвСру. */

 /* Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ стандартной ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ Π²Ρ‹Π·ΠΎΠ²Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ socket/connect ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ. */

 ClientSock = socket(AF_INET, SOCK_STREAM, 0);

 memset(&ClientSAddr, 0, sizeof(ClientSAddr));

 ClientSAddr.sin_family = AF_INET;

 if (argc >= 2) ClientSAddr.sin_addr.s_addr = inet_addr(argv [1]);

 else ClientSAddr.sin_addr.s_addr = inet_addr(DefaultIPAddr);

 ClientSAddr.sin_port = htons(SERVER_PORT);

 /* НомСр ΠΏΠΎΡ€Ρ‚Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Ρ€Π°Π²Π½Ρ‹ΠΌ 1070. */

 connect(ClientSock, (struct sockaddr *)&ClientSAddr, sizeof(ClientSAddr));

 /* Основной Ρ†ΠΈΠΊΠ» для Π²Ρ‹Π²ΠΎΠ΄Π° ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΡ Π½Π° Π²Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄, посылки запроса ΠΈ получСния ΠΎΡ‚Π²Π΅Ρ‚Π°. */

 while (!Quit) {

  _tprintf(_T("%s"), PromptMsg);

  /* Π’Π²ΠΎΠ΄ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹Ρ… строк, Π½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π° сСрвСру Π΄ΠΎΠ»ΠΆΠ½Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ASCII. */

  _fgetts(Req, MAX_RQRS_LEN-1, stdin); 

  for (j = 0; j <= _tcslen(Req) Request.Record[j] = Req[j];

  /* Π˜Π·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ символа Π½ΠΎΠ²ΠΎΠΉ строки Π² ΠΊΠΎΠ½Ρ†Π΅ строки. */

  Request.Record[strlen(Request.Record) – 1] = '\0';

  if (strcmp(Request.Record, QuitMsg) == 0 || strcmp(Request.Record, ShutMsg) == 0) Quit = TRUE;

  SendRequestMessage(&Request, ClientSock);

  ReceiveResponseMessage(&Response, ClientSock);

 }

 shutdown(ClientSock, 2); /* Π—Π°ΠΏΡ€Π΅Ρ‚ΠΈΡ‚ΡŒ посылку ΠΈ ΠΏΡ€ΠΈΠ΅ΠΌ сообщСний. */

 closesocket(ClientSock);

 WSACleanup();

 _tprintf(_T("\n****Π’Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· клиСнтской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹\n"));

 return 0;

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСрвСр Π½Π° основС сокСтов

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° serverSK (ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° 12.2) Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ serverNP (ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° 11.3), являясь Π΅Π΅ Π²ΠΈΠ΄ΠΎΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹ΠΌ ΠΈ ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠΌ.

β€’ Π’ ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½Π½ΠΎΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ сСрвСрныС ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΡŽ (on demand), Π° Π½Π΅ Π² Π²ΠΈΠ΄Π΅ ΠΏΡƒΠ»Π° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² фиксированного Ρ€Π°Π·ΠΌΠ΅Ρ€Π°. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° сСрвСр ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ запрос ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° соСдинСниС, создаСтся сСрвСрный Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΈ ΠΊΠΎΠ³Π΄Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ.

β€’ Π‘Π΅Ρ€Π²Π΅Ρ€ создаСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΡ€ΠΈΠ΅ΠΌΠ° (accept thread), Ρ‡Ρ‚ΠΎ позволяСт основному ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΎΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ„Π»Π°Π³ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹, ΠΏΠΎΠΊΠ° Π²Ρ‹Π·ΠΎΠ² accept остаСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ. Π₯отя сокСты ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒΡΡ ΠΊΠ°ΠΊ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ΡΡ, ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅. Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… возмоТностСй Winsock ΠΏΡ€ΠΈΠ·Π²Π°Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Windows Π΄Π°ΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π±ΠΎΠ»Π΅Π΅ простой ΠΈ Π±Π»ΠΈΠ·ΠΊΠΎΠΉ ΠΊ стандартам Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ синхронного Ρ€Π΅ΠΆΠΈΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ сокСтов.