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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QNX/UNIX: Анатомия ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ°Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 58

Автор ОлСг Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ

const char VERSION[] = "vers. 1.03";


// имя, ΠΏΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² пространствС

// ΠΈΠΌΠ΅Π½ наш тСстовый ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ рСсурса

static const char DEVNAME[_POSIX_PATH_MAX] = "/dev/srr";


// "базовая Ρ‡Π°ΡΡ‚ΡŒ" ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ devctl(), ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚

// Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ динамичСски Π½Π° основС этой части, Π½ΠΎ исходя

// ΠΈΠ· фактичСской Π΄Π»ΠΈΠ½Ρ‹ Π±Π»ΠΎΠΊΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…

const unsigned int DCMD_CMD = 1,

 DCMD_SRR = _POSIX_DEVDIR_TOFROM + (_DCMD_NET << 8) + DCMD_CMD;


// структура ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π° рСсурса ΠΏΠΎ запросу read()

struct result {

 pid_t pid;

 int chid;

 uint64_t cps;

 result(void) {

  pid = getpid();

  // Ссли ΡƒΠΆ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ, Ρ‚ΠΎ ΠΈ ΡΠ»ΡƒΠΆΠ΅Π±Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ;)

  cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;

 }

}


// Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ с ΠΈΠ·Π²Π΅Ρ‰Π΅Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹

inline void exit(const char *msg) {

 cout << '\r';

 perror(msg);

 exit(EXIT_FAILURE);

}

Π’ этой части ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π² заслуТиваСт Ρ€Π°Π·Π²Π΅ Ρ‡Ρ‚ΠΎ структура result. Наш сСрвСр устроСн Β«Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚Β»: ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ ΠΎΠ±ΠΌΠ΅Π½ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ½ осущСствляСт ΠΏΠΎ запросу devctl(), запрос read() Π½Π°ΠΌ Β«Π½Π΅ Π½ΡƒΠΆΠ΅Π½Β», ΠΈ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΅Π³ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ (PID + CHID) ΠΎΠ± Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½ΠΎΠΌ ΠΊΠ°Π½Π°Π»Π΅ ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями. Π—Π°ΠΎΠ΄Π½ΠΎ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ Π² ΠΏΠΎΠ»Π΅ cps этой структуры Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΡ‚ΠΎΠ²ΠΎΠΉ частоты процСссора сСрвСра, Ρ‡Ρ‚ΠΎ позволяСт Π·Π½Π°Ρ‚ΡŒ, «с ΠΊΠ΅ΠΌ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π΄Π΅Π»ΠΎΒ» ΠΏΡ€ΠΈ экспСримСнтах Π² сСти.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ Π²ΠΏΠΎΠ»Π½Π΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ сСрвСра. Π­Ρ‚ΠΎΡ‚ сСрвСр (Ρ„Π°ΠΉΠ» srv.cc), Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Ρ…, ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° нСзависимых ΠΊΠ°Π½Π°Π»Π° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ: ΠΊΠ°ΠΊ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ рСсурсов ΠΈ ΠΊΠ°ΠΊ сСрвСр простого ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями. Как ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ ΠΎΠ½ ΠΏΠΎ запросу read() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ адрСсныС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ (PID, CHID) для ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями (ND ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ). По запросу devctl(), Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎ запросу ΠΏΠΎ Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½ΠΎΠΌΡƒ ΠΊΠ°Π½Π°Π»Ρƒ ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями сСрвСр просто рСтранслируСт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±Π»ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ… (Π² ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ смыслС ΠΏΠΎ ΠΎΠ±ΠΎΠΈΠΌ ΠΊΠ°Π½Π°Π»Π°ΠΌ ΠΎΠ±ΠΌΠ΅Π½Π° наш сСрвСр являСтся Β«Π·Π΅Ρ€ΠΊΠ°Π»ΠΎΠΌΒ», ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠΌ Π΄Π°Π½Π½Ρ‹Π΅).

Π‘Π΅Ρ€Π²Π΅Ρ€ запросов

result data;


//---------------------------------------------------------

// рСализация ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° read()

static int readfunc(resmgr_context_t *ctp, io_read_t *msg,

 iofunc_ocb_t *ocb) {

 int sts = iofunc_read_verify(ctp, msg, ocb, NULL);

 if (sts != EOK) return sts;

 // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ статичСскиС Π΄Π°Π½Π½Ρ‹Π΅...

 MsgReply(ctp->rcvid, sizeof(result), &data, sizeof(result));

 return _RESMGR_NOREPLY;

}

//---------------------------------------------------------

// рСализация ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° devctl.

static int devctlfunc(resmgr_context_t *ctp, io_devctl_t *msg,

 iofunc_ocb_t *ocb) {

 int sts = iofunc_devctl_default(ctp, msg, ocb);

 if (sts != _RESMGR_DEFAULT) return sts;

 // Ρ€Π°Π·Π±ΠΎΡ€ динамичСски создаваСмого ΠΊΠΎΠ΄Π° devctl(),

 // ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· Π½Π΅Π³ΠΎ Π΄Π»ΠΈΠ½Ρ‹ принятого Π±Π»ΠΎΠΊΠ°

 unsigned int nbytes = (msg->i.dcmd - DCMD_SRR) >> 16;

 msg->o.nbytes = nbytes;

 // ΠΈ Ρ‚ΡƒΡ‚ ΠΆΠ΅ рСтрансляция Π±Π»ΠΎΠΊΠ° Π½Π°Π·Π°Π΄

 return _RESMGR_PTR(ctp, &msg->i, sizeof(msg->i) + nbytes);

}

//---------------------------------------------------------

// установка ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°, выполняСмая

// Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅

static void* install(void* data) {

 dispatch_t *dpp;

 if ((dpp = dispatch_create()) == NULL)

  exit("dispatch allocate");

 resmgr_attr_t resmgr_attr;

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

 resmgr_attr.nparts_max = 1;

 resmgr_attr.msg_max_size = 2048;

 static resmgr_connect_funcs_t connect_funcs;

 static resmgr_io_funcs_t io_funcs;

 iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,

  _RESMGR_IO_NFUNCS, &io_funcs);

 // опрСдСляСм ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ, ΠΎΡ‚Π»ΠΈΡ‡Π½ΡƒΡŽ ΠΎΡ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ,

 // Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π΄Π²ΡƒΡ… ΠΊΠΎΠΌΠ°Π½Π΄: read() & devctl()

 io_funcs.read = &readfunc;

 io_funcs.devctl = &devctlfunc;

 static iofunc_attr_t attr;

 iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

 // связываСм ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ с Π΅Π³ΠΎ прСфиксным ΠΈΠΌΠ΅Π½Π΅ΠΌ

 if (resmgr_attach(dpp, &resmgr_attr, DEVNAME,

  _FTYPE_ANY, 0, &connect_funcs, &io_funcs, &attr) == -1)

  exit("prefix attach");

 dispatch_context_t* ctp = dispatch_context_alloc(dpp);

 while (true) {

  if ((ctp = dispatch_block(ctp)) == NULL)

   exit("block error");

  dispatch_handler(ctp);

 }

}


// Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° для ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями,

// этого Π½Π°ΠΌ Ρ…Π²Π°Ρ‚ΠΈΡ‚ с большим запасом ΠΈ Π½Π°Π΄ΠΎΠ»Π³ΠΎ ;)

const int blk = 100000;

// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹Ρ… сообщСний,

// Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅

void* msginout(void* с) {

 static uint8_t bufin[blk];

 struct _msg_info info;

 while (true) {

  int rcvid = MsgReceive(data chid, &bufin, blk, &info);

  if (rcvid < 0) exit("message receive");

  if (MsgReply(rcvid, EOK, &bufin, info.msglen) < 0)

  exit("message reply");

 }

}

//--------------------------------------------------------

// "пустой" ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ Π½Π° ^C (сигнал SIGINT)

inline static void empty(int signo) {}

//--------------------------------------------------------

// главная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая всС это "хозяйство" установит

// ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π΅Π·Ρ€ΠΎΠΏΠΎΡ‚Π½ΠΎ ΠΆΠ΄Π°Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎ ^C ;)

int main(int argc, char *argv[]) {

 cout << "SRR server: " << VERSION << endl;

 // открываСтся ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ рСсурса ...

 int fd = open(DEVNAME, O_RDONLY);

 // Ссли ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ открылся, Ρ‚ΠΎ это Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ -

 // Π΄ΡƒΠ±Π»ΠΈΠΊΠ°Ρ‚Ρ‹ Π½Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ!

 if (fd > 0)

  close(fd), cout << "already in use " << DEVNAME << endl, exit(EXIT_FAILURE);

 // ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ Ρ€Π΅Π°ΠΊΡ†ΠΈΡŽ ^C:

 cout << ". . . . . . waiting ^C. . . . . ." << flush;

 signal(SIGINT, empty);

 // создаСтся ΠΊΠ°Π½Π°Π» для ΠΎΠ±ΠΌΠ΅Π½Π° Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΌΠΈ сообщСниями

 data.chid = ChannelCreate(0);

 // ΠΈ запускаСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ рСтранслятор с этого ΠΊΠ°Π½Π°Π»Π°

 if (pthread_create(NULL, NULL, msginout, NULL) != EOK)

  exit("message thread");

 // запускаСтся ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ рСсурса

 if (pthread_create(NULL, NULL, install, NULL) != EOK)

  exit("manager thread");

 // ... всС! ΠœΡ‹ своС Π΄Π΅Π»ΠΎ сдСлали ΠΈ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ ^C ...

 pause();

 cout << "\rFinalization... " << endl;

 // ... очистка, Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ...

 ChannelDestroy(data.chid);

 return EXIT_SUCCESS;

}

ΠŸΠ΅Ρ€Π²Π°Ρ клиСнтская ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° (Ρ„Π°ΠΉΠ» cli.cc) посылаСт сСрвСру Π±Π»ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹ (Π΄Π»ΠΈΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ Π² ΡˆΠΈΡ€ΠΎΠΊΠΈΡ… ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΈ запускС ΠΊΠ»ΡŽΡ‡Π° -b) ΠΈ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΎΡ‚ Π½Π΅Π³ΠΎ рСтрансляции, послС Ρ‡Π΅Π³ΠΎ замСряСт врСмя ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΎΡ‚ сСрвСра. Π­Ρ‚ΠΎΡ‚ процСсс повторяСтся ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ (ΠΊΠ»ΡŽΡ‡ -m).

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ клиСнтский процСсс

#include "common.h"


static uint64_t *tim;

static int num = 10;


// Π²Ρ‹Π²ΠΎΠ΄ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² с ΠΎΡ†Π΅Π½ΠΊΠΎΠΉ статистики: срСднСС, Π‘.К.О...

static void outtim(void) {

 double m = 0., s = 0.;

 for (int i = 0; i < num; i++) {

  double d = (double)tim[i];

  m += d;

  s += d * d;

 }

 m /= num;

 s = sqrt(s / num - m * m);

 cout << '\t' << (uint64_t)floor(m + 5) << "\t~" << (uint64_t)floor(s + .5) <<

  "\t{" << (uint64_t)floor(s / m * 100 + .5) << "%}" << endl;

}


int main(int argc, char **argv) {

 cout << "SRR client: " << VERSION << endl;

 int opt, val;

 unsigned int blk = 100;

 char PATH[_POSIX_PATH_MAX] = "";

 while ((opt = getopt(argc, argv, "n:b:m:")) != -1) {

  switch (opt) {

  case 'n': // имя хоста сСрвСра

   strcpy(PATH, "/net/");

   strcat(PATH, optarg);

   break;

  case 'b': // Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±Π»ΠΎΠΊΠ° ΠΎΠ±ΠΌΠ΅Π½Π° (Π±Π°ΠΉΡ‚)

   if (sscanf(optarg, "%i", &blk) != 1)

    exit("parse command line failed");

   break;

  case 'm': // число ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠΉ Ρ‚Π°ΠΊΠΈΡ… Π±Π»ΠΎΠΊΠΎΠ²

   if (sscanf(optarg, "%i", &num) != 1)

    exit("parse command line failed");

   break;

  default:

   exit(EXIT_FAILURE);

  }

 }

 // "ΡΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ" ΠΏΠΎΠ»Π½ΠΎΠ΅ имя ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°

 strcat(PATH, DEVNAME);

 cout << "server path. " << PATH << ", block size = "

  << blk << " bytes, repeat = " << num << endl;

 // ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΡ‹ сразу ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ процСссора ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

 result data;

 cout << "CPU speed [с.p.s ]: client = " << data.cps;

 // пытаСмся ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ ΠΊ сСрвСру-ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρƒ

 int fd = open(PATH, O_RDONLY);

 if (fd < 0) exit("server not found");

 // Ρ‡ΠΈΡ‚Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹

 if (read(fd, &data, sizeof(result)) == -1)

  exit("parameter block read");

 cout << ", server = " << data.cps << endl;