Самьюэл Алекс
Шрифт:
UNIX-сокеты используются для организации взаимодействия двух процессов, выполняющихся на одном компьютере. С другой стороны. Internet-сокеты позволяют соединять между собой процессы, работающие на разных компьютерах.
Пространству имен Internet соответствует константа
PF_INET
. Internet-сокеты чаще всего работают по протоколам TCP/IP. Протокол IP (Internet Protocol) отвечает за низкоуровневую доставку сообщений, осуществляя при необходимости их разбивку на пакеты и последующую компоновку. Доставка пакетов не гарантируется, поэтому они могут исчезать или приходить в неправильном порядке. Каждый компьютер в сети имеет свой IP-адрес. Протокол TCP (Transmission Control Protocol) функционирует поверх протокола IP и обеспечивает надежную доставку сообщений, ориентированную на установление соединений. DNS-имена
Легче запоминать имена а не числа, поэтому служба DNS (Domain Name Service) закрепляет за IP-адресами доменные имена вида
www.codesourcery.com
. Служба DNS организована в виде всемирной иерархии серверов имен. Чтобы использовать доменные имена в программах, нет необходимости разбираться в протоколах DNS Адрес Internet-сокета состоит из двух частей: адреса компьютера и номера порта. Эта информация хранится в структуре типа
sockaddr_in
. В поле sin_family
необходимо записать константу AF_INET
, указывающую на то, что адрес принадлежит пространству имен Internet. В поле sin_addr
хранится IP-адрес компьютера в виде 32-разрядного целого числа. Благодаря номерам портов можно различать сокеты, создаваемые на одном компьютере. В разных системах многобайтовые значения могут храниться с разным порядком следования байтов, поэтому с помощью функции htons
необходимо преобразовать номер порта в число с сетевым порядком следования байтов. Функция
gethostbyname
преобразует адрес компьютера из текстового представления — стандартного точечного (например, 10.10.10.1) или доменного (например, www.codesourcery.com
) — во внутреннее 32-разрядное. Функция возвращает указатель на структуру типа hostent
. IP-адрес находится в ее поле h_addr
. Программа, представленная в листинге 5.12, иллюстрирует работу с Internet-сокетами. Программа запрашивает начальную страницу у Web-сервера, адрес которого указан в командной строке.
Листинг 5.12. (socket-inet.c) Чтение страницы с Web-сервера
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
/* Отображение содержимого Web-страницы, полученной из
серверного сокета. */
void get_home_page(int socket_fd) {
char buffer[10000];
ssize_t number_characters_read;
/* Отправка HTTP-команды GET с запросом начальной страницы. */
sprintf(buffer, "GET /\n");
write(socket_fd, buffer, strlen(buffer));
/* Чтение данных из сокета. Функция read может вернуть
не все данные сразу, поэтому продолжаем чтение, пока
не будут получены все данные. */
while (1) {
number_characters_read = read(socket_fd, buffer, 10000);
if (number_characters_read == 0)
return;
/* Запись данных в стандартный выходной поток. */
fwrite(buffer, sizeof(char), number_characters_read, stdout);
}
}
int main(int argc, char* const argv[]) {
int socket_fd;
struct sockaddr_in name;
struct hostent* hostinfo;
/* Создание сокета. */
socket_fd = socket(PF_INET, SOCK_STREAM, 0);
/* Запись имени сервера в адресную структуру. */
name.sin_family = AF_INET;
/* Преобразование адреса из текстового представления во
внутреннюю форму. */
hostinfo = gethostbyname(argv[1]);
if (hostinfo == NULL)
return 1;
else
name sin_addr = *((struct in_addr*)hostinfo->h_addr);
/* Web-серверы используют порт 80. */
name.sin_port = htons(80);
/* Подключаемся к Web-серверу. */
if (connect(socket_fd, &name,
sizeof(struct sockaddr_in)) == -1) {
perror("connect");