Jump to content

Доменный сокет Unix

(Перенаправлено из сокета UNIX )

В клиент-серверных вычислениях сокет домена Unix — это сокет Беркли , который позволяет обмениваться данными между двумя процессами , выполняющимися на одном и том же Unix- или Unix-подобном хост-компьютере. [ 1 ] Это похоже на сокет домена Интернета , который позволяет обмениваться данными между двумя процессами, выполняющимися на разных хост-компьютерах.

Независимо от диапазона связи (тот же хост или другой хост), [ 2 ] Unix Компьютерные программы , выполняющие через сокеты, связь аналогичны. Единственное различие в способах связи — это метод преобразования имени в параметр адреса, необходимый для привязки соединения сокета. Для сокета домена Unix именем является /path/filename. Для сокета домена Интернета именем является IP address:Port number. В любом случае имя называется адресом . [ 3 ]

Два процесса могут взаимодействовать друг с другом, если каждый из них получает сокет. Серверный процесс привязывает свой сокет к адресу , открывает канал прослушивания , а затем непрерывно зацикливается . Внутри цикла серверный процесс приостанавливается в ожидании принятия клиентского соединения. [ 4 ] Приняв клиентское соединение , сервер затем выполняет чтения системный вызов , который блокирует ожидание . Клиент подключается сервера к сокету сервера через адрес . клиентский процесс записывает сообщение Затем для чтения серверным процессом. приложения Алгоритм может включать в себя несколько операций чтения/записи. По завершении алгоритма клиент выполняет exit()[ 5 ] и сервер выполняет close(). [ 6 ]

Для сокета домена Unix адрес сокета представляет собой /path/filename идентификатор. Сервер создаст /path/filename в файловой системе , чтобы действовать как файла блокировки семафор . В этом файле не происходит ввода-вывода, когда клиент и сервер отправляют сообщения друг другу. [ 7 ]

Сокеты впервые появились в Berkeley Software Distribution 4.2 (1983). [ 8 ] Он стал стандартом POSIX в 2000 году. [ 8 ] Интерфейс прикладного программирования был перенесен практически на каждую реализацию Unix и большинство других операционных систем. [ 8 ]

Создание экземпляра сокета

[ редактировать ]

И сервер, и клиент должны создать экземпляр объекта сокета , выполнив команду socket() системный вызов . Его использование: [ 9 ]

int socket( int domain, int type, int protocol );

The domain Параметр должен быть одним из следующих общих диапазонов связи : [ 10 ]

  1. В пределах одного хоста, используя константу AF_UNIX[ а ]
  2. Между двумя хостами по протоколу IPv4 с использованием константы AF_INET
  3. Между двумя хостами по протоколу IPv6 с использованием константы AF_INET6
  4. В пределах одного хоста или между двумя хостами через протокол передачи управления потоком с использованием константы SOCK_SEQPACKET[ 11 ]

Метка сокета домена Unix используется, когда domain значение параметра AF_UNIX. Метка сокета домена Интернета используется, когда domain значение параметра либо AF_INET или AF_INET6. [ 12 ]

The type Параметр должен быть одним из двух распространенных типов сокетов: поток или датаграмма. [ 10 ] Для экспериментального проектирования доступен третий тип сокета: необработанный.

  1. SOCK_STREAM создаст потоковый сокет. Потоковый сокет обеспечивает надежный, двунаправленный и ориентированный на соединение канал связи между двумя процессами. Данные передаются с использованием протокола управления передачей (TCP). [ 10 ]
  2. SOCK_DGRAM создаст дейтаграммный сокет. [ б ] Сокет дейтаграммы не гарантирует надежность и не поддерживает соединение . В результате передача происходит быстрее. Данные передаются с использованием протокола пользовательских дейтаграмм (UDP). [ 14 ]
  3. SOCK_RAW создаст Интернет-протокола (IP) сокет датаграммы . Сокет Raw пропускает транспортный уровень TCP/UDP и отправляет пакеты непосредственно на сетевой уровень . [ 15 ]

Для сокета домена Unix данные ( сетевые пакеты ) передаются между двумя подключенными процессами через транспортный уровень — TCP или UDP. [ 16 ] Для сокета интернет-домена данные передаются между двумя подключенными процессами через транспортный уровень и интернет-протокол (IP) сетевого уровня — TCP/IP или UDP/IP. [ 16 ]

The protocol Параметр должен быть установлен в ноль для потоковых и дейтаграммных сокетов. [ 2 ] Для необработанных сокетов protocol параметр должен быть установлен на IPPROTO_RAW. [ 9 ]

возвращаемое значение сокета()

[ редактировать ]
socket_fd = socket( int domain, int type, int protocol );

Как обычный файл open() системный вызов, socket() системный вызов возвращает дескриптор файла . [ 2 ] [ с ] Суффикс возвращаемого значения _fd означает файловый дескриптор .

Привязка сервера к /path/имя файла

[ редактировать ]

После создания экземпляра нового сокета сервер привязывает сокет к адресу. Для сокета домена Unix адресом является /path/filename.

Поскольку адрес сокета может быть либо /path/filename или IP_address:Port_number сокета , программный интерфейс приложения требует, чтобы адрес сначала был установлен в структуру. Для доменного сокета Unix структура следующая: [ 17 ]

struct sockaddr_un {
    sa_family_t sun_family; /* AF_UNIX */
    char sun_path[ 92 ];
}

The _un суффикс означает unix . Для сокета домена Интернета суффикс будет либо _in или _in6. sun_ префикс означает сокет unix . [ 17 ]

Компьютерная программа для создания и привязки потокового сокета домена Unix : [ 7 ]

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>

/* Should be 91 characters or less. Some Unix-like are slightly more. */
/* Use /tmp directory for demonstration only. */ 
char *socket_address = "/tmp/mysocket.sock";

void main( void )
{
    int server_socket_fd;
    struct sockaddr_un sockaddr_un = {0};
    int return_value;

    server_socket_fd = socket( AF_UNIX, SOCK_STREAM, 0 );
    if ( server_socket_fd == -1 ) assert( 0 );

    /* Remove (maybe) a prior run. */
    remove( socket_address );

    /* Construct the bind address structure. */
    sockaddr_un.sun_family = AF_UNIX;
    strcpy( sockaddr_un.sun_path, socket_address );

    return_value =
        bind(
            server_socket_fd,
            (struct sockaddr *) &sockaddr_un,
            sizeof( struct sockaddr_un ) );

    /* If socket_address exists on the filesystem, then bind will fail. */
    if ( return_value == -1 ) assert( 0 );

    /* Listen and accept code omitted. */
}

Второй параметр для bind() является указателем на struct sockaddr. Однако параметр, передаваемый в функцию, является адресом struct sockaddr_un. struct sockaddr это общая структура, которая не используется. Он определен в формального параметра объявлении для bind(). Поскольку каждый диапазон связи имеет свой собственный фактический параметр , эта общая структура была создана как заполнитель приведения. [ 18 ]

Сервер прослушивает соединение

[ редактировать ]

После привязки к адресу сервер открывает канал прослушивания порта , выполняя listen(). Его использование: [ 19 ]

int listen( int server_socket_fd, int backlog );

Фрагмент для прослушивания:

if ( listen( server_socket_fd, 4096 ) == -1 ) assert( 0 );

Для сокета домена Unix : listen() скорее всего добьюсь успеха и вернусь 0. Для сокета домена Интернета , если порт используется, listen() возвращает -1. [ 19 ]

The backlog Параметр задает размер очереди для ожидающих соединений. [ 20 ] Сервер может быть занят, когда клиент выполняет connect() запрос. Запросы на подключение до этого предела будут успешными. Если переданное значение невыполненной работы превышает максимум по умолчанию, то используется максимальное значение. [ 19 ]

Сервер принимает соединение

[ редактировать ]

После открытия канала прослушивания сервер входит в бесконечный цикл . Внутри цикла находится системный вызов accept(), который усыпляет себя. [ 4 ] accept() системный вызов вернет дескриптор файла при выполнении клиентского процесса connect(). [ 21 ]

Фрагмент для принятия соединения:

int accept_socket_fd;

while ( 1 )
{
    accept_socket_fd = accept( server_socket_fd, NULL, NULL );
    if ( accept_socket_fd == -1 ) assert( 0 );

    if ( accept_socket_fd ) > 0 ) /* client is connected */
}

Серверный ввод-вывод на сокете

[ редактировать ]

Когда accept() возвращает положительное целое число, сервер вступает в алгоритмический диалог с клиентом.

Ввод/вывод потокового сокета может выполнять вызовы обычной файловой системы read() и write(). [ 6 ] Однако больший контроль доступен, если потоковый сокет выполняет системные вызовы, специфичные для сокета: send() и recv(). Альтернативно, ввод/вывод сокета дейтаграммы должен выполнять системные вызовы, специфичные для сокета: sendto() и recvfrom(). [ 22 ]

Для базового сокета потока сервер получает данные с read( accept_socket_fd ) и отправляет данные с помощью write( accept_socket_fd ).

Фрагмент, иллюстрирующий ввод-вывод в базовом сокете потока:

int accept_socket_fd;

while ( 1 )
{
    accept_socket_fd = accept( server_socket_fd, NULL, NULL );
    if ( accept_socket_fd == -1 ) assert( 0 );

    if ( accept_socket_fd > 0 )
    {
        server_algorithmic_dialog( accept_socket_fd );
    }
}

#define BUFFER_SIZE 1024

void server_algorithmic_dialog(
    int accept_socket_fd )
{
    char input_buffer[ BUFFER_SIZE ];
    char output_buffer[ BUFFER_SIZE ];

    read( accept_socket_fd, input_buffer, BUFFER_SIZE );

    if ( strcasecmp( input_buffer, "hola" ) == 0 )
        strcpy( output_buffer, "Hola Mundo" );
    else
    if ( strcasecmp( input_buffer, "ciao" ) == 0 )
        strcpy( output_buffer, "Ciao Mondo" );
    else
        strcpy( output_buffer, "Hello World" );

    write( accept_socket_fd, output_buffer, strlen( output_buffer ) + 1 );
}

Сервер закрывает соединение

[ редактировать ]

Алгоритмический диалог заканчивается, когда алгоритм завершает работу или read( accept_socket_fd ) возвращает < 1. [ 6 ] Чтобы закрыть соединение, выполните команду close() системный вызов: [ 6 ]

Фрагмент для закрытия соединения:

int accept_socket_fd;

while ( 1 )
{
    accept_socket_fd = accept( server_socket_fd, NULL, NULL );
    if ( accept_socket_fd == -1 ) assert( 0 );

    if ( accept_socket_fd > 0 )
    {
        server_algorithmic_dialog( accept_socket_fd );
        close( accept_socket_fd );
    }
}

Фрагмент, иллюстрирующий конец диалога:

#define BUFFER_SIZE 1024

void server_algorithmic_dialog(
    int accept_socket_fd )
{
    char buffer[ BUFFER_SIZE ];
    int read_count;

    /* Omit algorithmic dialog */

    read_count = read( accept_socket_fd, buffer, BUFFER_SIZE );
    if ( read_count < 1 ) return;

    /* Omit algorithmic dialog */
}

Клиент создает экземпляр и подключается к /path/filename

[ редактировать ]

Компьютерная программа для клиента для создания экземпляра и подключения сокета: [ 5 ]

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>

/* Must match the server's socket_address. */
char *socket_address = "/tmp/mysocket.sock";

void main( void )
{
    int client_socket_fd;
    struct sockaddr_un sockaddr_un = {0};
    int return_value;

    client_socket_fd = socket( AF_UNIX, SOCK_STREAM, 0 );
    if ( client_socket_fd == -1 ) assert( 0 );

    /* Construct the client address structure. */
    sockaddr_un.sun_family = AF_UNIX;
    strcpy( sockaddr_un.sun_path, socket_address );

    return_value =
       connect(
            client_socket_fd,
            (struct sockaddr *) &sockaddr_un,
            sizeof( struct sockaddr_un ) );

    /* If socket_address doesn't exist on the filesystem,   */
    /* or if the server's connection-request queue is full, */
    /* then connect() will fail.                            */
    if ( return_value == -1 ) assert( 0 );

    /* close( client_socket_fd ); <-- optional */

    exit( EXIT_SUCCESS );
}

Клиентский ввод-вывод на сокете

[ редактировать ]

Если connect() возвращает ноль, клиент может вступить в алгоритмический диалог с сервером. Клиент может отправлять потоковые данные через write( client_socket_fd ) и может получать потоковые данные через read( client_socket_fd ).

Фрагмент, иллюстрирующий клиентский ввод-вывод в сокете потока:

{
    /* Omit construction code */
    return_value =
        connect(
            client_socket_fd,
            (struct sockaddr *) &sockaddr_un,
            sizeof( struct sockaddr_un ) );

    if ( return_value == -1 ) assert( 0 );

    if ( return_value == 0 )
    {
        client_algorithmic_dialog( client_socket_fd );
    }

    /* close( client_socket_fd ); <-- optional */

    /* When the client process terminates,     */
    /* if the server attempts to read(),       */
    /* then read_count will be either 0 or -1. */
    /* This is a message for the server        */
    /* to execute close().                     */
    exit( EXIT_SUCCESS );
}

#define BUFFER_SIZE 1024

void client_algorithmic_dialog(
    int client_socket_fd )
{
    char buffer[ BUFFER_SIZE ];
    int read_count;

    strcpy( buffer, "hola" );
    write( client_socket_fd, buffer, strlen( buffer ) + 1 );
    read_count = read( client_socket_fd, buffer, BUFFER_SIZE );

    if ( read_count > 0 ) puts( buffer );
}

См. также

[ редактировать ]
  • Конвейер (Unix) — механизм межпроцессного взаимодействия с использованием передачи сообщений.
  • Netlink — интерфейс ядра Linux для межпроцессного взаимодействия между процессами.
  1. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1149. ИСБН  978-1-59327-220-3 . Сокеты — это метод IPC, который позволяет обмениваться данными между приложениями как на одном хосте (компьютере), так и на разных хостах, соединенных сетью.
  2. ^ Перейти обратно: а б с Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1150. ИСБН  978-1-59327-220-3 .
  3. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1150. ИСБН  978-1-59327-220-3 . Сервер привязывает свой сокет к известному адресу (имени), чтобы клиенты могли его найти.
  4. ^ Перейти обратно: а б Стивенс, Ричард В.; Феннер, Билл; Рудофф, Эндрю М. (2004). Сетевое программирование Unix (3-е изд.). Пирсон Образование. п. 14. ISBN  81-297-0710-1 . Обычно серверный процесс приостанавливается при вызове Accept , ожидая прибытия и принятия клиентского соединения.
  5. ^ Перейти обратно: а б Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1169. ИСБН  978-1-59327-220-3 .
  6. ^ Перейти обратно: а б с д Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1159. ИСБН  978-1-59327-220-3 .
  7. ^ Перейти обратно: а б Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1166. ИСБН  978-1-59327-220-3 .
  8. ^ Перейти обратно: а б с Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1149. ИСБН  978-1-59327-220-3 .
  9. ^ Перейти обратно: а б Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1153. ИСБН  978-1-59327-220-3 .
  10. ^ Перейти обратно: а б с Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1151. ИСБН  978-1-59327-220-3 .
  11. ^ Перейти обратно: а б «Руководство программиста Linux (unix — сокеты для локального межпроцессного взаимодействия)» . 30 апреля 2018 года . Проверено 22 февраля 2019 г.
  12. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1197. ИСБН  978-1-59327-220-3 .
  13. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1183. ИСБН  978-1-59327-220-3 .
  14. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1152. ИСБН  978-1-59327-220-3 .
  15. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1184. ИСБН  978-1-59327-220-3 .
  16. ^ Перейти обратно: а б Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1181. ИСБН  978-1-59327-220-3 .
  17. ^ Перейти обратно: а б Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1165. ИСБН  978-1-59327-220-3 .
  18. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1154. ИСБН  978-1-59327-220-3 .
  19. ^ Перейти обратно: а б с «Страница руководства Linux для Listen()» .
  20. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1157. ИСБН  978-1-59327-220-3 .
  21. ^ «Страница руководства Linux для Accept()» .
  22. ^ Керриск, Майкл (2010). Программный интерфейс Linux . Нет крахмального пресса. п. 1160. ИСБН  978-1-59327-220-3 .

Примечания

[ редактировать ]
  1. ^ Альтернативно, PF_UNIX или AF_LOCAL можно использовать. [ 11 ] AF означает «Семейство адресов», а PF означает «Семейство протоколов».
  2. ^ дейтаграммы Сокет не следует путать с дейтаграмм, пакетом используемым на сетевом уровне . [ 13 ]
  3. ^ В UNIX все является файлом .


Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 456d8764cb8f4485fae3b07ff49ef17b__1724338200
URL1:https://arc.ask3.ru/arc/aa/45/7b/456d8764cb8f4485fae3b07ff49ef17b.html
Заголовок, (Title) документа по адресу, URL1:
Unix domain socket - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)