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

ЖАНРЫ

TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security)

Фейт Сидни М.

Шрифт:

4. getsockname(sockMain, &servAddr, &length);

Использовать getsockname, чтобы извлечь присвоенный socket порт.

5. msgLength = recvfrom(sockMain, buf, BUFLEN, 0, &clientAddr, &length);

Вызов recvfrom имеет форму:

recvfrom(дескриптор_socket, входной_буфер, длина_буфера, флаги, исходная_адресная_структура, указатель_на_длину_исходной_адресной_структуры)

Флаги позволяют вызывающей стороне просмотреть сообщение без его фактического получения.

После возвращения исходная адресная структура заполняется IP-адресом и номером порта клиента. Необходим указатель на длину исходного адреса, поскольку она может быть изменена при вставке в поле фактического адреса клиента.

6. inet_ntoa(clientAddr.sin_addr);

Этот вызов преобразует 32-разрядный адрес Интернета клиента в знакомую нам нотацию этого адреса с точками и десятичными значениями.

21.11 Клиентская программа UDP

Клиент соединяется с сервером, посылает одно сообщение и закрывает соединение. При запуске программы конечный пользователь должен ввести имя хоста, порт сервера и отправляемое на сервер сообщение. Например:

udpclient plum.cs.yale.edu 2315 "Это сообщение."

/* udpclient.с

 * Перед запуском клиента следует запустить сервер.

 * Далее нужно получить порт сервера.

 * Для запуска клиента ввести:

 * udpclient имя_хоста порт сообщение */

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <stdio.h>

#include <errno.h>

main(argc, argv)

 int argc;

 char *argv[]; /* Это вводимые пользователем аргументы. */

/* argv[0] - имя программы. argv[1] указывает на имя хоста. */

/* argv[2] ссылается на порт, */

/* а argv [3] ссылается на текстовое сообщение. */

{

 int sock;

 struct sockaddr_in, servAddr, clientAddr;

 struct hostent *hp, *gethostbyname;

 /* Должно быть четыре аргумента. */

 if (argc < 4) {

printf ("ВВЕСТИ udpclient имя_хоста порт сообщение\n");

exit(1);

 }

 /* 1. Создать socket для UDP. */

 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

perror("He получен socket\n");

exit(1);

 }

 /* 2. Занести адрес и порт
сервера в servAddr.

* Сначала заполнить адресную структуру нулями.

* Использовать функцию gethostbyname для получения имени хоста

* и его IP-адреса. Затем скопировать IP-адрес

* в servAddr функцией bcopy.

* Наконец занести номер порта из argv[2]. */

 bzero((char *)&servAddr, sizeof(servAddr));

 servAddr.sin_family = AF_INET;

 hp = gethostbyname(argv[1]);

 bcopy(hp->h_addr, &servAddr.sin_addr, hp->h_length);

 servAddr.sin_port = htons(atoi(argv[2]));

 /* 3. Вызвать bind для получения порта UDP. Система

* назначает свободный порт. */

 bzero((char *)&clientAddr, sizeof(clientAddr));

 clientAddr.sin_family = AF_INET;

 clientAddr.sin_addr.s_addr = htonl(INADDR_ANY);

 clientAddr.sin_port = 0;

 if (bind(sock, &clientAddr, sizeof(clientAddr)) < 0) {

perror("Клиент не получил порт.\n");

exit(1);

 }

 /* 4. Клиент анонсирует свою готовность к приему сообщений.

* Он посылает сообщение и распечатывает последнюю строку. */

 printf ("CLIENT: Готов к пересылке\n");

 if (sendto(sock, argv[3], strlen(argv[3]), 0, &servAddr, sizeof(servAddr)) < 0) {

perror "Проблема с sendto.\n");

exit(1);

 }

 printf ("CLIENT: Пересылка закончена. Счастливо.\n");

 /* Закрытие socket */

 close(sock);

}

21.11.1 Запросы в клиентской программе UDP

1. sock = socket(AF_INET, SOCK_DGRAM, 0); UDP клиента создает socket для UDP.

2. bzero((char *)&servAddr, sizeof(servAddr));

servAddr.sin_family = AF_INET;

hp = gethostbyname(argv[1]);

bcopy(hp->h_addr, &servAddr.sin_addr, hp->length);

servAddr.sin_port = htons(atoi(argv[2]));

Структура servAddr заполнена введенными конечным пользователем значениями, как это делалось и в клиенте для TCP.

3. bind (sock, &clientAddr, sizeof(clientAddr)); Клиент вызывает bind для получения порта.

Поделиться с друзьями: