Чтение онлайн

на главную - закладки

Жанры

Linux: Полное руководство

Аллен Питер В.

Шрифт:
Обмен данными в режиме SOCK_DGRAM

Функция sendto позволяет отправить данные по протоколу UDP (без установления соединения), указав при этом узел-приемник:

extern ssize_t sendto(int __fd, __const void *__buf,

 size_t __n, int __flags, __CONST_SOCKADDR_ARG __addr,

 socklen_t __addr_len) __THROW;

Назначение первых четырех аргументов такое же, как и функции send, а последние два аргумента задают структуру типа struct sockaddr_in, содержащую информацию об адресе узла-приемника, и размер этой структуры соответственно. Аргумент

__addr
— это адрес структуры sockaddr_in, а не она сама!

Как и функция send, функция sendto возвращает количество байтов отправленных данных или -1, если произошла ошибка.

Функция recvfrom позволяет получить данные по протоколу UDP:

extern ssize_t recvfrom(int __fd, void *__restrict __buf,

size_t __n, int __flags, __SOCKADDR_ARG __addr,

socklen_t *__restrict __addr_len) __THROW;

Назначение первых четыре аргументов такое же, как и у функции recv. Предпоследний аргумент позволяет указать структуру, в которую будет записана информация об адресе узла-отправителя. Помните: нужно передать адрес структуры, а не саму структуру. Последний параметр задает длину этой структуры.

Функция возвращает количество принятых данных или -1 в случае ошибки. Проверить ошибку можно и по-другому: если структура адреса узла отправителя пуста (равна NULL), значит, произошла ошибка.

27.3.6. Завершение сеанса связи

Для закрытия сеанса связи можно использовать один из двух системных вызовов: close или shutdown.

Системный вызов close также используется для закрытия файлов. Вот прототип этой функции:

int close(int __fd);

Данной функции нужно передать всего один параметр — дескриптор сокета.

Однако вызов close использовать не рекомендуется из-за специфики его работы: он закрывает сокет грубо, не дожидаясь завершения передачи данных. В результате использования close вероятность повреждения принимаемых или передаваемых данных очень высока. В принципе, использовать close можно на клиенте, но на сервере это недопустимо: сначала нужно использовать shutdown, а потом уже close.

Вызов shutdown используется для завершения сеанса связи, при этом еще не переданные данные будут переданы другой стороне. Прототип функции:

extern int shutdown(int __fd, int __how) __THROW;

Первый параметр — это дескриптор сокета, а второй может принимать одно из трех значений:

♦ SHUT_RD (или 0) — передать данные, которые еще не переданы, но их отправка уже началась, и больше не принимать данные для чтения.

♦ SHUT_WR (или 1) — передать данные и запретить прием данных через сокет.

♦ SHUT_RDWR (или 2) — передать данные и запретить вообще обмен через сокет — ни приема, ни передачи.

27.3.7. Программа-сервер

В этом пункте мы напишем две программы — сервер и клиент. Программа-сервер после запуска сразу же перейдет в режим ожидания («прослушивания») новых клиентов. Максимальное количество клиентов —3. Как только подключится клиент, сервер отправит ему сообщение «What is your name?», в ответ на которое клиент передаст свое имя — «Denis». Сервер прочитает переданную клиентом информацию и выведет ее на консоль. Клиент, в свою очередь, выведет на консоль запрос сервера.

С целью упрощения исходного кода как сервера, так и клиента, обработку ошибок производить не будем, поэтому будьте готовы к тому, что ваш клиент выдаст сообщение Segmentation fault в ответ на неверно заданные параметры. Я рекомендую в качестве имени сервера использовать

localhost
и обе программы запускать на одном компьютере — это же только демонстрация.

Вот исходный код программы-сервера:

Листинг 27.3. Программа-сервер

#include <sys/types.h>

#include <netdb.h>

#include <memory.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

#define SERVER_PORT 1234

#define BUF_SIZE 64

#define MSG_TO_SEND "What is your name?\n"

int main {

 int sock1, sock2;

 int ans_len, total=0;

 char buffer[BUF_SIZE];

 struct sockaddr_in sin, client;

 sock1 = socket(AF_INET, SOCK_STREAM, 0);

 memset((char *)&sin, '\0', sizeof(sin));

 sin.sin_family = AF_INET;

 sin.sin_addr.s_addr = INADDR_ANY;

 sin.sin_port = SERVER_PORT;

 bind(sock1, (struct sockaddr *)&sin, sizeof(sin));

 printf("Server running...\n");

 listen(sock1, 3);

 while (1) {

ans_len = sizeof(client);

sock2 = accept(sock1, &client, &ans_len);

write(sock2, MSG_TO_SEND, sizeof(MSG_TO_SEND));

total+=1;

ans_len = read(sock2, buffer, BUF_SIZE);

write(1, buffer, ans_len);

printf("Client no %d\n", total);

shutdown(sock2, 0);

Поделиться:
Популярные книги

Точка Бифуркации V

Смит Дейлор
5. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации V

Я уже князь. Книга XIX

Дрейк Сириус
19. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я уже князь. Книга XIX

По прозвищу Святой. Книга первая

Евтушенко Алексей Анатольевич
1. Святой
Фантастика:
попаданцы
альтернативная история
6.40
рейтинг книги
По прозвищу Святой. Книга первая

Законы Рода. Том 14

Андрей Мельник
14. Граф Берестьев
Фантастика:
аниме
фэнтези
эпическая фантастика
5.00
рейтинг книги
Законы Рода. Том 14

Третий Генерал: Том VI

Зот Бакалавр
5. Третий Генерал
Фантастика:
городское фэнтези
аниме
сказочная фантастика
попаданцы
гаремник
5.00
рейтинг книги
Третий Генерал: Том VI

Неудержимый. Книга XVIII

Боярский Андрей
18. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVIII

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Школа пластунов

Трофимов Ерофей
Одиночка
Фантастика:
боевая фантастика
5.00
рейтинг книги
Школа пластунов

Дважды одаренный. Том V

Тарс Элиан
5. Дважды одаренный
Фантастика:
аниме
альтернативная история
городское фэнтези
5.00
рейтинг книги
Дважды одаренный. Том V

Мастер 11

Чащин Валерий
11. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 11

Идеальный мир для Лекаря 5

Сапфир Олег
5. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 5

Тайны затерянных звезд. Том 1

Лекс Эл
1. Тайны затерянных звезд
Фантастика:
боевая фантастика
космическая фантастика
фэнтези
5.00
рейтинг книги
Тайны затерянных звезд. Том 1

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл

Эволюционер из трущоб. Том 9

Панарин Антон
9. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 9