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

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:

ssize_t sendto(int sockfd, const void * buff, size_t nbytes, int flags,

const struct sockaddr * to, socklen_t addrlen);

Обе функции возвращают количество записанных или прочитанных байтов в случае успешного выполнения, -1 в случае ошибки

Первые три аргумента,

sockfd
,
buff
и
nbytes
, идентичны первым трем аргументам
функций
read
и
write
: дескриптор, указатель на буфер, из которого производится чтение или в который происходит запись, и число байтов для чтения или записи.

Мы расскажем об аргументе

flags
в главе 14, где мы рассматриваем функции
recv
,
send
,
recvmsg
и
sendmsg
, поскольку сейчас в нашем простом примере они не нужны. Пока мы всегда будем устанавливать аргумент
flags
в нуль.

Аргумент to для функции

sendto
— это структура адреса сокета, содержащая адрес протокола (например, IP-адрес и номер порта) адресата. Размер этой структуры адреса сокета задается аргументом
addrlen
. Функция
recvform
заполняет структуру адреса сокета, на которую указывает аргумент from, записывая в нее протокольный адрес отправителя дейтаграммы. Число байтов, хранящихся в структуре адреса сокета, также возвращается вызывающему процессу в целом числе, на которое указывает аргумент
addrlen
. Обратите внимание, что последний аргумент функции
sendto
является целочисленным значением, в то время как последний аргумент функции
recvfrom
— это указатель на целое значение (аргумент типа «значение-результат»).

Последние два аргумента функции recvfrom аналогичны двум последним аргументам функции

accept
: содержимое структуры адреса сокета по завершении сообщает нам, кто отправил дейтаграмму (в случае UDP) или кто инициировал соединение (в случае TCP). Последние два аргумента функции
sendto
аналогичны двум последним аргументам функции
connect
: мы заполняем структуру адреса сокета протокольным адресом получателя дейтаграммы (в случае UDP) или адресом узла, с которым будет устанавливаться соединение (в случае TCP).

Обе функции возвращают в качестве значения функции длину данных, которые были прочитаны или записаны. При типичном использовании функции

recvfrom
с протоколом дейтаграмм возвращаемое значение — это объем пользовательских данных в полученной дейтаграмме.

Дейтаграмма может иметь нулевую длину. В случае UDP при этом возвращается дейтаграмма IP, содержащая заголовок IP (обычно 20 байт для IPv4 или 40 байт для IPv6), 8-байтовый заголовок UDP и никаких данных. Это также означает, что возвращаемое из функции

recvfrom
нулевое значение вполне приемлемо для протокола дейтаграмм: оно не является признаком того, что собеседник закрыл соединение, как это происходит при возвращении нулевого значения из функции
read
на сокете TCP. Поскольку протокол UDP не ориентирован на установление соединения, то в нем и не существует такого события, как закрытие соединения.

Если аргумент from функции

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

И функция

recvfrom
, и функция
sendto
могут использоваться с TCP, хотя обычно в этом нет необходимости.

8.3. Эхо-сервер UDP: функция main

Теперь мы переделаем нашу простую

модель клиент-сервер из главы 5, используя UDP. Диаграмма вызовов функций в программах наших клиента и сервера UDP показана на рис. 8.1. На рис. 8.2 представлены используемые функции. В листинге 8.1 [1] показана функция сервера
main
.

1

Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.

Рис. 8.2. Простая модель клиент-сервер, использующая UDP

Листинг 8.1. Эхо-сервер UDP

//udpcliserv/udpserv01.с

1 #include "unp.h"

2

3 intmain(int argc, char **argv)

4 {

5 int sockfd;

6 struct sockaddr_in servaddr, cliaddr;

7 sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

8 bzero(&servaddr, sizeof(servaddr));

9 servaddr.sin_family = AF_INET;

10 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

11 servaddr.sin_port = htons(SERV_PORT);

12 Bind(sockfd, (SA*)&servaddr, sizeof(servaddr));

13 dg_echo(sodkfd, (SA*)&cliaddr, sizeof(cliaddr));

14 }

Создание сокета UDP, связывание с заранее известным портом при помощи функции bind

7-12
Мы создаем сокет UDP, задавая в качестве второго аргумента функции
socket
значение
SOCK_DGRAM
(сокет дейтаграмм в протоколе IPv4). Как и в примере сервера TCP, адрес IPv4 для функции bind задается как
INADDR_ANY
, а заранее известный номер порта сервера — это константа
SERV_PORT
из заголовка
unp.h
.

13
Затем вызывается функция
dg_echo
для обработки клиентского запроса сервером.

8.4. Эхо-сервер UDP: функция dg_echo

В листинге 8.2 показана функция

dg_echo
.

Листинг 8.2. Функция dg_echo: отражение строк на сокете дейтаграмм

//lib/dg_echo.c

1 #include "unp.h"

2 void

3 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

4 {

5 int n;

6 socklen_t len;

7 char mesg[MAXLINE];

8 for (;;) {

9 len = clilen;

10 n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);

11 Sendto(sockfd, mesg, n, 0, pcliaddr, len);

12 }

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

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Помещица Бедная Лиза

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Помещица Бедная Лиза

Бальмануг. Студентка

Лашина Полина
2. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Бальмануг. Студентка

Изменить нельзя простить

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Изменить нельзя простить

Газлайтер. Том 3

Володин Григорий
3. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 3

Жандарм 4

Семин Никита
4. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 4

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Отмороженный 6.0

Гарцевич Евгений Александрович
6. Отмороженный
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Отмороженный 6.0

Пипец Котенку!

Майерс Александр
1. РОС: Пипец Котенку!
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Пипец Котенку!

АН (цикл 11 книг)

Тарс Элиан
Аномальный наследник
Фантастика:
фэнтези
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
АН (цикл 11 книг)

Толян и его команда

Иванов Дмитрий
6. Девяностые
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Толян и его команда

Пятое правило дворянина

Герда Александр
5. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Пятое правило дворянина

Игрок, забравшийся на вершину. Том 8

Михалек Дмитрий Владимирович
8. Игрок, забравшийся на вершину
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Игрок, забравшийся на вершину. Том 8

Возвышение Меркурия. Книга 7

Кронос Александр
7. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 7