Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция 9.docx
Скачиваний:
88
Добавлен:
17.06.2016
Размер:
65.52 Кб
Скачать

Листинг 9.7 – Использование gethostbyname()

#include <stdlib.h>

#include <stdio.h>

#include <netdb.h>

/* paddr: печатает IP – адрес в стандартном точечно-десятичном виде */

void paddr(unsigned char *a) {

printf("%d.%d.%d.%d\n", a[0], a[1], a[2], a[3]); }

void main(int argc, char **argv) {

struct hostent *hp;

char *host = "google.com";

int i;

hp = gethostbyname(host);

if (!hp) {

fprintf(stderr, "could not obtain address of %s\n", host); return 0; }

for (i=0; hp->h_addr_list[i] != 0; i++)

paddr((unsigned char*)

hp->h_addr_list[i]);

exit(0);

}

В листинге 9.8 приведен фрагмент кода для отправки сообщения от клиента серверу. Предполагается что имя хоста задается в host. Переменная fd – идентификатор (дескриптор) сокета, который был создан вызовом socket() (см. ранее).

Листинг 9.8 – Пример отправки сообщения серверу

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <string.h>

struct hostent *hp;

/* информация о хосте*/

struct sockaddr_in servaddr;

/* адрес сервера */

char *my_messsage = "это тестовое сообщение";

/* заполняем структуру */

memset((char*)&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port);

/* получаем адрес сервера по имени*/

hp = gethostbyname(host);

if (!hp) {

fprintf(stderr, "невозможно получить адрес %s\n", host);

return 0; }

/* помещаем полученный адрес в адресную структуру */

memcpy((void *)&servaddr.sin_addr, hp->h_addr_list[0], hp->h_length);

/* посылаем сообщение серверу */

if (sendto(fd, my_message, strlen(my_message), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {

perror("ошибка sendto"); return 0;

}

4.Получение сообщения от клиента сервером

В случае TCP, сервер переводит сокет в режим прослушивания среды передачи при помощи системного вызова listen(), после чего производит создание нового соединения при помощи функции accept (). UDP – протокол без установления соединения. Сервер (как и в случае клиента) может сразу же после создания сокета принимать дейтаграммы. Для данных целей используется метод recvfrom (), который переводит программу( вернее нить процесса) в режим ожидания входящих дейтаграмм на указанный IP-адрес и порт.

Функция recvfrom имеет следующий синтаксис:

int recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict src_addr, socklen_t *restrict *src_len)

  • socket – созданный и привязанный (bind) сокет. Номер порта указанный при связывании сокета будет именно тем портом, на котором recvfrom будет ожидать дейтаграммы;

  • buffer – указатель на буфер, в который будут приниматься данные;

  • length – размер буфера в байтах;

  • flags - параметр позволяет обрабатывать внесеансовые(out-of-band) данные, получить сообщение без извлечения его из очереди, или блокировать до тех пор пока запрос не будет полностью выполнен. Для практики можно положить равным 0, однако если на мое мыло будет направлено письмо с детальным описанием возможных значений флагов (ну и расшифровка) до 27.04 вам будет +1 балл за экзамен. Акция распространяется на первого написавшего письмо с ответом на мое мыло;

  • src_addr – параметр – указатель на адресную структуру sockaddr, которая автоматически заполняется при получении дейтаграммы и содержит адресную информацию отправителя дейтаграммы.

  • src_len – длина созданной адресной структуры. В случае если нет необходимости в идентификации отправителя можно положить равной 0.

Функция recvfrom возвращает число байт, которое было прочитано в буфер buffer.

Создадим простейший сервер(Листинг 9.9). Создадим сокет, привяжем его ко всем доступным адресам на машине, но четко специфицируем номер порта. Затем будем в цикле принимать сообщения и печатать их содержимое.

Соседние файлы в папке Лекции