Linux: Полное руководство
Шрифт:
Функция sendto позволяет отправить данные по протоколу UDP (без установления соединения), указав при этом узел-приемник:
Назначение первых четырех аргументов такое же, как и функции send, а последние два аргумента задают структуру типа struct sockaddr_in, содержащую
Как и функция send, функция sendto возвращает количество байтов отправленных данных или -1, если произошла ошибка.
Функция recvfrom позволяет получить данные по протоколу UDP:
Назначение первых четыре аргументов такое же, как и у функции recv. Предпоследний аргумент позволяет указать структуру, в которую будет записана информация об адресе узла-отправителя. Помните: нужно передать адрес структуры, а не саму структуру. Последний параметр задает длину этой структуры.
Функция возвращает количество принятых данных или -1 в случае ошибки. Проверить ошибку можно и по-другому: если структура адреса узла отправителя пуста (равна NULL), значит, произошла ошибка.
27.3.6. Завершение сеанса связи
Для закрытия сеанса связи можно использовать один из двух системных вызовов: close или shutdown.
Системный вызов close также используется для закрытия файлов. Вот прототип этой функции:
Данной функции нужно передать всего один параметр — дескриптор сокета.
Однако вызов close использовать не рекомендуется из-за специфики его работы: он закрывает сокет грубо, не дожидаясь завершения передачи данных. В результате использования close вероятность повреждения принимаемых или передаваемых данных очень высока. В принципе, использовать close можно на клиенте, но на сервере это недопустимо: сначала нужно использовать shutdown, а потом уже close.
Вызов shutdown используется для завершения сеанса связи, при этом еще не переданные данные будут переданы другой стороне. Прототип функции:
Первый параметр — это дескриптор сокета, а второй может принимать одно из трех значений:
♦ SHUT_RD (или 0) — передать данные, которые еще не переданы, но их отправка уже началась, и больше не принимать данные для чтения.
♦ SHUT_WR (или 1) — передать данные и запретить прием данных через сокет.
♦ SHUT_RDWR (или 2) — передать данные и запретить вообще обмен через сокет — ни приема, ни передачи.
27.3.7.
В этом пункте мы напишем две программы — сервер и клиент. Программа-сервер после запуска сразу же перейдет в режим ожидания («прослушивания») новых клиентов. Максимальное количество клиентов —3. Как только подключится клиент, сервер отправит ему сообщение «What is your name?», в ответ на которое клиент передаст свое имя — «Denis». Сервер прочитает переданную клиентом информацию и выведет ее на консоль. Клиент, в свою очередь, выведет на консоль запрос сервера.
С целью упрощения исходного кода как сервера, так и клиента, обработку ошибок производить не будем, поэтому будьте готовы к тому, что ваш клиент выдаст сообщение Segmentation fault в ответ на неверно заданные параметры. Я рекомендую в качестве имени сервера использовать
Вот исходный код программы-сервера:
Листинг 27.3. Программа-сервер