Составители:
Рубрика:
Листинг 2 Использование функции connect ()
/***************************************************************/
/*** Фрагмент программы, демонстрирующий инициализацию ***/
/*** параметров и вызов функции connect(). ***/
/***************************************************************/
#define PORTJTIME 13
struct sockaddr_in dest;
char *host = "127.0.0.1";
int sd;
/**** Создание сокета ****/
...
bzero(&dest, sizeof(dest)); /* обнуляем структуру */
dest.sin_family = AF_INET; /* выбираем протокол */
dest.sin_port = htons(PORT_TIME); /* выбираем порт */
inet_aton(host, &dest.sin_addr); /* задаем адрес */
if ( connect(sd, &dest, sizeof(dest)) != 0 ) /* подключаемся! */
{
perror("socket connection");
abort();
}
Перед подключением к серверу выполняется ряд подготовительных действий. В первую очередь
создается структура sockaddr_in. Затем объявляется переменная, содержащая адрес, по которому будет
произведено обращение. После этого выполняются другие, не показанные здесь, операции, включая вы-
зов функции socket(). Функция bzero() заполняет структуру sockaddr_in нулями. Поле sin family устанав-
ливается равным AF_INET. Далее задаются номер порта и IP-адрес. Функции htons () и
inet_aton(), вы-
полняющие преобразования типов данных, рассматриваются в главе 2, "Основы TCP/IP".
Наконец, осуществляется подключение к серверу. Обратите внимание на необходимость провер-
ки значения, возвращаемого функцией connect(). Это один из многих приемов, позволяющих повысить
надежность сетевых приложений.
После установления соединения дескриптор сокета, sd, становится дескриптором ввода-вывода,
доступным обеим программам. Большинство серверов ориентировано на выполнение
единственной
транзакции, после чего разрывают соединение (например, сервер HTTP 1.0 отправляет запрашиваемый
файл и отключается). Взаимодействуя с такими серверами, программа должна посылать запрос, полу-
чать ответ и закрывать сокет.
Получение ответа от сервера
Итак, сокет открыт, и соединение установлено. Можно начинать разговор. Некоторые серверы
инициируют диалог подобно людям, разговаривающим по телефону. Они как бы говорят: "Алло!" При-
ветственное сообщение может включать имя сервера и определенные инструкции.
Когда сокет открыт, можно вызывать стандартные низкоуровневые функции ввода-вывода для
приема и передачи данных. Ниже приведено объявление
функции read():
#include <unistd.h>
ssize_t read(int fd, void *buf, size t count);
Эта функция должна быть вам знакома. Вы много раз применяли ее при работе с файлами, только
на этот раз необходимо указывать дескриптор не файла (fd), а сокета (sd) , Вот как обычно организуется
вызов функции функции read () :
...
int sd, bytes_read;
sd = socket(PF_INET, SOCK_STREAM, 0); /* создание сокета */
/**** Подключение к серверу ****/
bytes_read = read(sd, buffer, MAXBUF); /* чтение данных */
if ( bytes_read < 0 )
/* сообщить об ошибках; завершить работу */
Дескриптор сокета можно даже преобразовать в файловый дескриптор (FILE*), если требуется
работать с высокоуровневыми функциями ввода-вывода. Например, в следующем фрагменте программы
демонстрируется, как применить функцию fscanf() для чтения данных с сервера (строки, на которые
следует обратить внимание, выделены полужирным шрифтом):
char Name[NAME], Address[ADDRESS], Phone[PHONE];
FILE *sp;
Листинг 2 Использование функции connect () /***************************************************************/ /*** Фрагмент программы, демонстрирующий инициализацию ***/ /*** параметров и вызов функции connect(). ***/ /***************************************************************/ #define PORTJTIME 13 struct sockaddr_in dest; char *host = "127.0.0.1"; int sd; /**** Создание сокета ****/ ... bzero(&dest, sizeof(dest)); /* обнуляем структуру */ dest.sin_family = AF_INET; /* выбираем протокол */ dest.sin_port = htons(PORT_TIME); /* выбираем порт */ inet_aton(host, &dest.sin_addr); /* задаем адрес */ if ( connect(sd, &dest, sizeof(dest)) != 0 ) /* подключаемся! */ { perror("socket connection"); abort(); } Перед подключением к серверу выполняется ряд подготовительных действий. В первую очередь создается структура sockaddr_in. Затем объявляется переменная, содержащая адрес, по которому будет произведено обращение. После этого выполняются другие, не показанные здесь, операции, включая вы- зов функции socket(). Функция bzero() заполняет структуру sockaddr_in нулями. Поле sin family устанав- ливается равным AF_INET. Далее задаются номер порта и IP-адрес. Функции htons () и inet_aton(), вы- полняющие преобразования типов данных, рассматриваются в главе 2, "Основы TCP/IP". Наконец, осуществляется подключение к серверу. Обратите внимание на необходимость провер- ки значения, возвращаемого функцией connect(). Это один из многих приемов, позволяющих повысить надежность сетевых приложений. После установления соединения дескриптор сокета, sd, становится дескриптором ввода-вывода, доступным обеим программам. Большинство серверов ориентировано на выполнение единственной транзакции, после чего разрывают соединение (например, сервер HTTP 1.0 отправляет запрашиваемый файл и отключается). Взаимодействуя с такими серверами, программа должна посылать запрос, полу- чать ответ и закрывать сокет. Получение ответа от сервера Итак, сокет открыт, и соединение установлено. Можно начинать разговор. Некоторые серверы инициируют диалог подобно людям, разговаривающим по телефону. Они как бы говорят: "Алло!" При- ветственное сообщение может включать имя сервера и определенные инструкции. Когда сокет открыт, можно вызывать стандартные низкоуровневые функции ввода-вывода для приема и передачи данных. Ниже приведено объявление функции read(): #includessize_t read(int fd, void *buf, size t count); Эта функция должна быть вам знакома. Вы много раз применяли ее при работе с файлами, только на этот раз необходимо указывать дескриптор не файла (fd), а сокета (sd) , Вот как обычно организуется вызов функции функции read () : ... int sd, bytes_read; sd = socket(PF_INET, SOCK_STREAM, 0); /* создание сокета */ /**** Подключение к серверу ****/ bytes_read = read(sd, buffer, MAXBUF); /* чтение данных */ if ( bytes_read < 0 ) /* сообщить об ошибках; завершить работу */ Дескриптор сокета можно даже преобразовать в файловый дескриптор (FILE*), если требуется работать с высокоуровневыми функциями ввода-вывода. Например, в следующем фрагменте программы демонстрируется, как применить функцию fscanf() для чтения данных с сервера (строки, на которые следует обратить внимание, выделены полужирным шрифтом): char Name[NAME], Address[ADDRESS], Phone[PHONE]; FILE *sp;
Страницы
- « первая
- ‹ предыдущая
- …
- 6
- 7
- 8
- 9
- 10
- …
- следующая ›
- последняя »