socket_fd = socket(PF_LOCAL, SOCK_STREAM, 0);

 /* Переход в режим сервера. */

 name.sun_family = AF_LOCAL;

 strcpy(name.sun_path, socket_name);

 bind(socket_fd, SUN_LEN(&name));

 /* Ожидание запросов. */

 listen(socket_fd, 5);

 /* Непрерывный прием запросов на подключение. Для каждого

    клиента вызывается функция server(). Цикл продолжается,

    пока не будет получено сообщение "quit". */

 do {

  struct sockaddr_un client_name;

  socklen_t client_name_len;

  int client_socket_fd;

  /* Прием запроса. */

  client_socket_fd =

   accept(socket_fd, &client_name, &client_name_len);

  /* Обработка запроса. */

  client_sent_quit_message = server(client_socket_fd);

  /* Закрытие серверной стороны соединения. */

  close(client_socket_fd);

 } while(!client_sent_quit_message);

 /* Удаление файла локального сокета. */

 close(socket_fd);

 unlink(socket_name);

 return 0;

}

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

Листинг 5.11. (socket-client.c) Клиент локального сокета

#include

#include

#include

#include

#include

/* Запись строки TEXT в сокет, заданный

   дескриптором SOCKET_FD. */

void write_text(int socket_fd, const char* text) {

 /* Сначала указывается число байтов в строке, включая

    завершающий символ NULL. */

 int length = strlen(text) + 1;

 write(socket_fd, &length, sizeof(length));

 /* Запись строки. */

 write(socket_fd, text, length);

}

int main(int argc, char* const argv[]) {

 const char* const socket_name = argv[1];

 const char* const message = argv[2];

 int socket_fd;

 struct sockaddr_un name;

 /* Создание сокета. */

 socket_fd = socket(PF_LOCAL, SOCK_STREAM. 0);

 /* Сохранение имени сервера в адресной структуре. */

 name.sun_family = AF_LOCAL;

 strcpy(name.sun_path, socket_name);

 /* Подключение к серверному сокету. */

 connect(socket_fd, &name, SUN_LEN(&name));

 /* передача сообщения, заданного в командной строке. */

 write_text(socket_fd, message);

 close(socket_fd);

 return 0;

}

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

Чтобы проверить этот пример, запустите в одном терминальном окне серверную программу, указав путь к сокету, например:

% ./socket-server /tmp/socket

В другом окне запустите несколько раз клиентскую программу, задав тот же путь к сокету плюс требуемое сообщение:

% ./socket-client /tmp/socket "Hello, world."

% ./socket-client /tmp/socket "This is a test."

Сервер получит и отобразит эти сообщения. Чтобы закрыть сервер, пошлите ему сообщение "quit":

% ./socket-client /tmp/socket "quit"

<p>5.5.6. Internet-сокеты</p>

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

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

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