Читаем Операционная система UNIX полностью

 /* Адреса транспортных узлов сервера и клиента */

 struct sockaddr_in serv_addr, *clnt_addr;

 struct hostent *hp;

 char buf[80], hname[80];

 struct t_bind req;

 struct t_call *call;

 /* Создадим транспортный узел. В качестве поставщика

    транспортных услуг выберем модуль TCP */

 if ((tn = t_open("/dev/tcp", O_RDWR, NULL)) == -1) {

  t_error("Ошибка вызова t_open()");

  exit(1);

 }

 /* Зададим адрес транспортного узла — он должен быть

    известен клиенту */

 nport = PORTNUM;

 /* Приведем в соответствие порядок следования байтов для хоста

    и сети */

 nport = htons((u_short)nport);

 bzero(&serv_addr, sizeof(serv_addr));

 serv_addr.sin_family = AF_INET;

 serv_addr.sin_addr.s_addr = INADDR_ANY;

 serv_addr.sin_port = nport;

 req.addr.maxlen = sizeof(serv_addr);

 req.addr.len = sizeof(serv_addr);

 req.addr.buf = (char*)&serv_addr;

 /* Максимальное число запросов, ожидающих обработки,

    установим равным 5 */

 req.qlen = 5;

 /* Свяжем узел с запросом */

 if (t_bind(tn, &req, (struct t_bind*)0) < 0) {

  t_error("Ошибка вызова t_bind();

  exit(1);

 }

 fprintf(stderr, "Адрес сервера: %s\n",

  inet_ntoa(serv_addr.sin_addr));

 /* Поскольку в структуре t_call нам понадобится только буфер

    для хранения адреса клиента, разместим ее динамически */

 if ((call =

  (struct t_call*)t_alloc(tn, T_CALL, T_ADDR)) == NULL) {

  t_error("Ошибка вызова t_alloc()");

  exit(2);

 }

 call->addr.maxlen = sizeof(serv_addr);

 call->addr.len = sizeof(srv_addr);

 call->opt.len = 0;

 call->update.len = 0;

 /* Бесконечный цикл получения и обработки запросов */

 while (1) {

  /* Ждем поступления запроса на установление соединения */

  if (t_listen(s, call) < 0) {

   t_error("Ошибка вызова t_listen()");

   exit(1);

  }

  /* Выведем информацию о клиенте, сделавшем запрос */

  clnt_addr = (struct sockaddr_in*)call->addr.buf;

  printf("Клиент: %s\n", inet_ntoa(clnt_addr->sin_addr));

  /* Создадим транспортный узел для обслуживания запроса */

  if (ntn = t_open("/dev/tcp", O_RDWR, (struct t_info*)0)) < 0) {

   t_error("Ошибка вызова t_open()");

   exit(1);

  }

  /* Пусть система сама свяжет его с подходящим адресом */

  if (t_bind(ntn, (struct t_bind*)0), (struct t_bind*)0) < 0) {

   t_error("Ошибка вызова t_accept()");

   exit(1);

  }

  /* Примем запрос и переведем его обслуживание на новый

     транспортный узел */

  if (t_accept(tn, ntn, call) < 0) {

   t_error("Ошибка вызова t_accept()");

   exit(1);

  }

  /* Создадим новый процесс для обслуживания запроса.

     При этом родительский процесс продолжает принимать

     запросы от клиентов */

  if ((pid = fork()) == -1) {

   t_error("Ошибка вызова fork()");

   exit(1);

  }

  if (pid == 0) {

   int nbytes;

   /* Дочерний процесс: этот транспортный узел уже не нужен,

Перейти на страницу:

Похожие книги