Изменить стиль страницы

   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;