Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПОКС.docx
Скачиваний:
69
Добавлен:
26.05.2015
Размер:
1.82 Mб
Скачать

Пример использования локальных сокетов

В листинге 5.10 представлена программа сервера, в которой создается локальный сокет и слушает запросы на соединения с сервером. При получении запроса на соединение, сервер читает текстовые сообщения, передаваемые через соединение и печатает их. Если одно из этих сообщений - "выход", программа сервера удаляет сокет и завершается. Программа socket-server предполагает, что путь к сокету передается через параметр командной строки.

Листинг 5.10 (socket-server.c)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <unistd.h>

/* Чтение текста из сокета и вывод его на печать. Продолжение цикла до закрытия сокета.

* В качестве результата возвратит не ноль, если клиент передал сообщение "quit", иначе 0 */

int server (int client_socket)

{

while (1) {

int length;

char* text;

/* Сначала из сокета прочитать длину текстого сообщения. Если в качестве результата возвратиться 0,

то клиент закрыл соединение */

if (read (client_socket, &ength, sizeof (length)) == 0)

return 0;

/* выделить место в буфере для хранения текста */

text = (char*) malloc (length);

/* Чтение текста и распечатка */

read (client_socket, text, length);

printf ("%s\n", text);

/* Освободить буфер */

free (text);

/* Если от клиента поступило сообщение "quit", завершить работу */

if (!strcmp (text, "quit"))

return 1;

}

}

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

{

const char* const socket_name = argv[1];

int socket_fd;

struct sockaddr_un name;

int client_sent_quit_message;

/* Создать сокет */

socket_fd = socket (PF_LOCAL, SOCK_STREAM, 0);

/* Определить что это сервер */

name.sun_family = AF_LOCAL;

strcpy (name.sun_path, socket_name);

bind (socket_fd, &name, 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, соединяется с локальным сокетом и посылает сообщения. Путь к сокету и сообщения передаtтся через командную строку.

Листинг 5.11(socket-client.c)

#include <stdio.h>

#include <string.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <unistd.h>

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

void write_text (int socket_fd, const char* text)

{

/* Записать в строку количество байт, включая NUL-терминал */

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. Сервер сохраняет размер сообщения, для выделения памяти под сообщение. Чтобы выполнить этот пример, необходимо запустить сервер-программу в одном окне, определить путь к сокету.

Например, /tmp/socket .

% ./socket-server /tmp/socket

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

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

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

Сервер-программа получает и печатает эти сообщения. Для закрытия соединения, клиент посылает сообщение "quit":

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

Сервер-программа завершена.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]