17.4.2. Ожидание соединения

17.4.2. Ожидание соединения

Как объяснялось выше, ожидание установки соединения на сокете домена Unix придерживается следующей процедуры: создание сокета, привязка адреса к сокету, перевод системы в режим ожидания соединений и принятие соединения.

Ниже показан пример простого сервера, который многократно принимает соединения с сокетом домена Unix (файл sample-socket в текущем каталоге) и считывает все данные из сокета, посылая их на стандартный вывод.

 1: /* userver.c */

 2:

 3: /* Ожидает соединения на сокете ./sample-socket домена Unix.

 4:    После установки соединения копирует данные

 5:    из сокета в stdout до тех пор, пока вторая сторона не

 6:    закрывает соединение. Далее ожидает следующее соединение

 7:    с сокетом. */

 8:

 9: #include <stdio.h>

10: #include <sys/socket.h>

11: #include <sys/un.h>

12: #include <unistd.h>

13:

14: #include "sockutil.h" /* некоторые служебные функции */

15:

16: int main (void) {

17:  struct sockaddr_un address;

18:  int sock, conn;

19:  size_t addrLength;

20:

21:  if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)

22:   die("socket");

23:

24:  /* Удалить все сокеты (или файлы), существовавшие ранее */

25:  unlink("./sample-socket");

26:

27:  address.sun_family = AF_UNIX; /* сокет домена Unix */

28:  strcpy(address.sun_path, "./sample-socket");

29:

30:  /* Общая длина адреса, включая элемент

31:     sun_family */

32:  addrLength = sizeof(address.sun_family) +

33:  strlen(address.sun_path);

34:

35:  if (bind(sock, (struct sockaddr *) &address, addrLength))

36:   die("bind");

37:

38:  if (listen(sock, 5))

39:   die("listen");

40:

41:  while ((conn = accept(sock, (struct sockaddr *) &address,

42:   &addrLength)) >=0) {

43:   printf("---- получение данных ");

44:   copyData(conn, 1);

45:   printf("---- готово ");

46:   close(conn);

47:  }

48:

49:  if (conn < 0)

50:   die("accept");

51:

52:  close(sock);

53:  return 0;

54: }

Несмотря на небольшой размер приведенной программы, она хорошо иллюстрирует, как написать простой серверный процесс. Этот сервер является итеративным, поскольку он обрабатывает только одного клиента за раз. Можно создавать также параллельные серверы, управляющие несколькими клиентами одновременно[124].

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

Серверный код приводит тип указателя struct sockaddr_un, передаваемого и в bind(), и в accept(), к (struct sockaddr *). При прототипировании различных системных вызовов, относящихся к сокетам, предполагается, что они принимают указатель на struct sockaddr. Приведение типа предотвращает появление уведомлений от компилятора о несоответствии типов указателей.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

7.4 ОЖИДАНИЕ ЗАВЕРШЕНИЯ ВЫПОЛНЕНИЯ ПРОЦЕССА

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

7.4 ОЖИДАНИЕ ЗАВЕРШЕНИЯ ВЫПОЛНЕНИЯ ПРОЦЕССА Процесс может синхронизировать продолжение своего выполнения с моментом завершения потомка, если воспользуется системной функцией wait. Синтаксис вызова функции:pid = wait(stat_addr);где pid — значение кода идентификации (PID)


7.4. Блокировка и ожидание

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

7.4. Блокировка и ожидание Продемонстрируем теперь, что взаимные исключения предназначены для блокирования, но не для ожидания. Изменим наш пример из предыдущего раздела таким образом, чтобы потребитель запускался сразу же после запуска всех производителей. Это даст


7.5. Условные переменные: ожидание и сигнализация

Из книги Системное программирование в среде Windows автора Харт Джонсон М

7.5. Условные переменные: ожидание и сигнализация Взаимное исключение используется для блокирования, а условная переменная — для ожидания. Это два различных средства синхронизации, и оба они нужны. Условная переменная представляет собой переменную типа pthread_cond_t. Для


Ожидание завершения процесса

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

Ожидание завершения процесса Простейшим, но наряду с этим и обладающим наиболее ограниченными возможностями, методом синхронизации с другим процессом является ожидание его завершения. Представленные ниже стандартные функции ожидания Windows обладают рядом интересных


Ожидание завершения потока

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

Ожидание завершения потока Поток может дожидаться завершения выполнения другого потока точно так же, как потоки могут дожидаться завершения процесса, что обсуждалось в главе 6. В этом случае при вызове функций ожидания (WaitForSingleObject и WaitForMultipleObjects) вместо дескрипторов


Ожидание сообщений и объектов

Из книги QNX/UNIX [Анатомия параллелизма] автора Цилюрик Олег Иванович

Ожидание сообщений и объектов Функция MsgWaitForMultipleObjects аналогична функции WaitForMultipleObjects. Применяйте ее для того, чтобы разрешить потоку или процессу обработку событий пользовательского интерфейса, таких как щелчки мышью, во время ожидания перехода объектов синхронизации в


13.2.7. Ожидание события

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

13.2.7. Ожидание события Часто один или несколько потоков следят за «внешним миром», а остальные выполняют полезную работу. Все примеры в этом разделе надуманные, но общий принцип они все же иллюстрируют.В следующем примере прикладную задачу решают три потока. Четвертый


10.5.1. Запуск и ожидание с помощью system()

Из книги автора

10.5.1. Запуск и ожидание с помощью system() Программам часто требуется запускать другие программы и ожидать их завершения, прежде чем продолжать свою работу. Функция system() позволяет это делать достаточно просто.int system (const char* cmd);system() порождает дочерний процесс, который


12.2.6. Ожидание сигналов

Из книги автора

12.2.6. Ожидание сигналов Когда программа построена преимущественно вокруг сигналов, часто необходимо, чтобы она ожидала появления какого-то сигнала, прежде чем продолжать работу. Системный вызов pause() предоставляет простую возможность для этого.#include <unistd.h>int


17.3.4. Ожидание соединений

Из книги автора

17.3.4. Ожидание соединений После создания сокета сервер привязывает к нему адрес с помощью функции bind(). Далее процесс сообщает системе путем вызова функции listen(), что он готов разрешить другим процессам соединение с данным сокетом (по указанному адресу). Если сокет привязан


17.5.7. Ожидание TCP-соединений

Из книги автора

17.5.7. Ожидание TCP-соединений Ожидание соединений TCP происходит почти идентично ожиданию соединений домена Unix. Единственные различия заключаются в семействах протоколов и адресов. Ниже показан вариант примера сервера домена Unix, который работает через сокеты TCP. 1: /* tserver.с


Ожидание условия

Из книги автора

Ожидание условия Простое ожиданиеint pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);Вызов функции блокирует вызвавший поток на условной переменной cond и разблокирует мьютекс mutex. Поток блокируется до тех пор, пока другой поток не вызовет функцию разблокирования на условной


Ожидание завершения потока

Из книги автора

Ожидание завершения потока Ожидание родительским потоком завершения одного или нескольких порожденных им «присоединенных» потоков (на вызове pthread_join()) — это простейший и эффективный вариант синхронизации потоков, не требующий для своей реализации каких-либо


Ожидание на барьере

Из книги автора

Ожидание на барьере Функция ожидания (синхронизации) на барьере:int pthread_barrier_wait(pthread_barrier_t* barrier);Вызов этой функции приводит к блокированию потока до тех пор, пока на барьере не накопится количество заблокированных потоков, определенное ранее при вызове функции


3.4.1. Ожидание завершения процесса

Из книги автора

3.4.1. Ожидание завершения процесса Читатели, запускавшие программу fork-exec (см. листинг 3.4), должно быть, обратили внимание на то, что вывод команды ls часто появляется после того, как основная программа уже завершила свою работу. Это связано с тем, что дочерний процесс, в