Литмир - Электронная Библиотека
Содержание  
A
A

В одной-единственной главе мы не сможем дать исчерпывающее описание всех многообразных сетевых возможностей Linux, поэтому вы найдете здесь лишь основные программные сетевые интерфейсы, которые позволят вам писать собственные программы, работающие в сети.

Более подробно мы рассмотрим следующие темы:

□ как действует соединение с помощью сокетов;

□ атрибуты сокетов, адреса и обмен информацией;

□ сетевая информация и интернет-демон (inetd/xinetd);

□ клиенты и серверы.

Что такое сокет?

Сокет — это средство связи, позволяющее разрабатывать клиент-серверные системы для локального, на одной машине, или сетевого использования. Функции ОС Linux, такие как вывод, подключение к базам данных и обслуживание Web-страниц, равно как и сетевые утилиты, например

rlogin
, предназначенная для удаленной регистрации, и
ftp
, применяемая для передачи файлов, обычно используют сокеты для обмена данными.

Сокеты создаются и используются не так, как каналы, потому что они подчеркивают явное отличие между клиентом и сервером. Механизм сокетов позволяет создавать множество клиентов, присоединенных к единственному серверу.

Соединения на базе сокетов

Соединения на базе сокетов можно рассматривать как телефонные звонки в учреждение. Телефонный звонок поступает в организацию, и на него отвечает секретарь приемной, направляющий вызов в соответствующий отдел (серверный процесс) и оттуда к нужному сотруднику (сокет сервера). Каждый входящий телефонный звонок (клиент) направляется к соответствующей конечной точке, и промежуточные операторы могут заниматься последующими телефонными звонками. Прежде чем рассматривать установку соединений с помощью сокетов в системах Linux, нужно понять, как они ведут себя в приложениях сокетов, поддерживающих соединения.

Сначала серверное приложение создает сокет, который как файловый дескриптор представляет собой ресурс, присваиваемый единственному серверному процессу. Сервер создает его с помощью системного вызова

socket
, и этот сокет не может использоваться совместно с другими процессами.

Далее сервер присваивает сокету имя. Локальные сокеты с заданными именами файлов в файловой системе Linux часто размещаются в каталоге /tmp или /usr/tmp. У сетевых сокетов имя файла будет идентификатором сервиса (номер порта/точка доступа), относящегося к конкретной сети, к которой могут подключаться клиенты. Этот идентификатор, задавая определенный номер порта, соответствующий корректному серверному процессу, позволяет Linux направлять входящие подключения по определенному маршруту. Например, Web-сервер обычно создает сокет для порта 80, идентификатор, зарезервированный для этой цели. Web-обозреватели знают о необходимости применять порт 80 для своих HTTP-подключений к Web- сайтам, которые пользователь хочет читать. Именуется сокет с помощью системного вызова

bind
. Далее серверный процесс ждет подключения клиента к именованному сокету. Системный вызов
listen
формирует очередь входящих подключений. Сервер может принять их с помощью системного вызова
accept
.

Когда сервер вызывает

accept
, создается новый сокет, отличающийся от именованного сокета. Этот новый сокет применяется только для взаимодействия с данным конкретным клиентом. Именованный сокет сохраняется для дальнейших подключений других клиентов. Если сервер написан корректно, он может извлечь выгоду из многочисленных подключений. Web-сервер добивается этого за счет одновременного предоставления страниц многих клиентам. В случае простого сервера все последующие клиенты ждут в очереди до тех пор, пока сервер не будет готов снова.

Клиентская сторона системы с применением сокетов гораздо проще. Клиент создает неименованный сокет с помощью вызова

socket
. Затем он вызывает
connect
для подключения к серверу, используя в качестве адреса именованный сокет сервера.

Будучи установлены, сокеты могут применяться как низкоуровневые файловые дескрипторы, обеспечивая двунаправленный обмен данными.

Выполните упражнения 15.1 и 15.2.

Упражнение 15.1. Простой локальный клиент

Далее приведен пример очень простой клиентской программы client1.с. В ней неименованный сокет создается и затем подключается к сокету сервера, названному

server_socket
. Системный вызов
socket
мы подробно рассмотрим чуть позже, когда будем обсуждать некоторые проблемы адресации.

1. Включите нужные заголовочные файлы и задайте переменные:

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <sys/un.h>

#include <unistd.h>

#include <stdlib.h>

int main() {

 int sockfd;

 int len;

 struct sockaddr_un address;

 int result;

 char ch = 'A';

2. Создайте сокет для клиента:

 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

3. Назовите сокет по согласованию с сервером:

 address.sun_family = AF_UNIX;

 strcpy(address.sun_path, "server_socket");

 len = sizeof(address);

4. Соедините ваш сокет с сокетом сервера:

 result = connect(sockfd, (struct sockaddr *)&address, len);

 if (result == -1) {

  perror("oops : client1");

  exit(1);

 }

5. Теперь вы можете читать и писать через

sockfd
:

 write(sockfd, &ch, 1);

 read(sockfd, &ch, 1);

 printf("char from server = %c\n", ch);

 close(sockfd);

 exit(0);

}

Эта программа завершится аварийно, если вы попытаетесь выполнить ее, потому что еще не создан именованный сокет сервера, (Точное сообщение об ошибке может отличаться в разных системах.)

$ <b>./client1</b>

oops: client1: No such file or directory

$

Упражнение 15.2. Простой локальный сервер

Далее приведена программа простого сервера server1.с, которая принимает запрос на соединение от клиента. Она создает сокет сервера, присваивает ему имя, создает очередь ожидания и принимает запросы на соединения.

1. Включите необходимые заголовочные файлы и задайте переменные:

262
{"b":"285844","o":1}