Вход/Регистрация
Операционная система UNIX
вернуться

Робачевский Андрей Михайлович

Шрифт:

Приведенный пример в качестве транспортного протокола использует TCP. Это значит, что перед передачей прикладных данных клиент должен установить соединение с сервером. Эта схема, приведенная на рис. 6.17, несколько отличается от рассмотренной в разделе "Межпроцессное взаимодействие в BSD UNIX. Сокеты", где передача данных осуществлялась без предварительного установления связи и в данном случае соответствовала бы использованию протокола UDP.

Рис. 6.17. Схема установления связи и передачи данных между клиентом и сервером

В соответствии с этой схемой сервер производит связывание с портом, номер которого предполагается известным для клиентов bind(2), и сообщает о готовности приема запросов listen(2)). При получении запроса он с помощью функции accept(2) создает новый сокет, который и обслуживает обмен данными между клиентом и сервером. Для того чтобы сервер мог продолжать обрабатывать поступающие запросы, он порождает отдельный процесс на каждый поступивший запрос. Дочерний процесс, в свою очередь, принимает сообщения от клиента (recv(2)) и передает их обратно (send(2)).

Клиент не выполняет связывания, поскольку ему безразлично, какой адрес будет иметь его коммуникационный узел. Эту операцию выполняет система, выбирая свободный адрес порта и установленный адрес хоста. Далее клиент направляет запрос на установление соединения (connect(2)), указывая адрес сервера (IP-адрес и номер порта). После установления соединения ("тройное рукопожатие") клиент передает сообщение (send(2)), принимает от сервера ответ recv(2)) и выводит его на экран.

В программе используются несколько функций, которые не рассматривались. Эти функции значительно облегчают жизнь программисту, выполняя, например, такие действия, как трансляцию доменного имени хоста в его IP-адрес (gethostbyname(3N)), приведение в соответствие порядка следования байтов в структурах данных, который может различаться для хоста и сети (htons(3N)), а также преобразование IP-адресов и их составных частей в соответствии с привычной "человеческой" нотацией, например 127.0.0.1 (inet_ntoa(3N)). Мы не будем подробнее останавливаться на этих функциях, предоставляя читателю самостоятельно обратиться к соответствующим разделам электронного справочника man(1).

Ниже приведены тексты программ сервера и клиента.

Сервер

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <fcntl.h>

#include <netdb.h>

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

#define PORTNUM 1500

main(argc, argv)

int argc;

char *argv[];

{

 int s, ns;

 int pid;

 int nport;

 struct sockaddr_in serv_addr, clnt_addr;

 struct hostent* hp;

 char buf[80], hname[80];

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

к сетевому формату */

 nport = PORTNUM;

 nport = htons((u_short)nport);

 /* Создадим сокет, использующий протокол TCP */

 if ((s=socket(AF_INET, SOCK_STREAM, 0))==-1) {

perror("Ошибка вызова socket");

exit(1);

 }

 /* Зададим адрес коммуникационного узла */

 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;

 /* Свяжем сокет с этим адресом */

 if (bind(s, struct sockaddr*)&serv_addr,

sizeof(serv_addr))==-1) {

perror("Ошибка вызова bind");

exit(1);

 }

 /* Выведем сообщение с указанием адреса сервера */

  • Читать дальше
  • 1
  • ...
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: