Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сало залік.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
133 Кб
Скачать
☆

56. Використання низькорівневих сокетів

Низькорівневі сокети відкривають перед вами нові горизонти. Вони надають програмісту повний контроль над вмістом пакетів , які відправляються в подорож по мережі. З іншого боку , вони складніше у використанні і володіють поганою переносимістю . Ось чому використовувати їх слід тільки у разі потреби. Наприклад , без них не обійтися при розробці системних утиліт типу пінг і трасування .

Насамперед з'ясуємо, чим низькорівневі сокети відрізняються від звичайних. Працюючи з звичайними сокетами , ви передаєте системі "чисті" дані , а вона сама піклується про додавання до них необхідних заголовків ( а іноді ще й кінцевиків ) . Наприклад , коли ви посилаєте повідомлення через UPD- сокет , до нього додається спочатку UDP - заголовок , потім IP- заголовок , а в самому кінці - заголовок апаратного протоколу , який використовується у вашій локальній мережі (наприклад , Ethernet). У результаті виходить кадр , показаний на малюнку 1 .

Низькорівневі сокети дозволяють вам включати в буфер з даними заголовки деяких протоколів. Наприклад , ви можете включити в ваше повідомлення TCP - або UDP - заголовок , надавши системі сформувати для вас IP- заголовок , а можете взагалі сформувати всі заголовки самостійно. Зрозуміло, при цьому вам доведеться вивчити роботу відповідних протоколів і строго дотримати формат їх заголовків , інакше програма працювати не буде.

При роботі з низькорівневими сокетами вам доведеться вказувати в третьому параметрі функції сокет той протокол , до заголовків якого ви хочете отримати доступ. Константи для основних протоколів Інтернет оголошені у файлі netinet / in.h. Вони мають вигляд IPPROTO_XXX , де ХХХ -назва протоколу : IPPROTO_TCP , IPPROTO_UDP , IPPROTO_RAW (в останньому випадку ви отримаєте можливість попрацювати з " сирим " IP і формувати IP- заголовки вручну).

Лістинг 5 . Програма відправник з використанням низькорівневих сокетів.

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

struct UdpHeader

{

u_short src_port;

u_short targ_port;

u_short length;

u_short checksum;

};

char message[] = "Hello there!\n";

char msgbuf[1024];

int main()

{

int sock;

struct sockaddr_in addr;

struct UdpHeader header;

sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);

if(sock < 0)

{

perror("socket");

exit(1);

}

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

header.targ_port = htons(3425);

header.length = htons(sizeof(header)+sizeof(message));

header.checksum = 0;

memcpy((void *)msgbuf, (void *)&header, sizeof(header));

memcpy((void *)(msgbuf+sizeof(header)), (void *)message, sizeof(message));

sendto(sock, msgbuf, sizeof(header)+sizeof(message), 0,

(struct sockaddr *)&addr, sizeof(addr));

close(sock);

return 0;

}

57. Функції для роботи з dns та адресами

DNS ( Domain Name Service , Domain Name Space , Domain Name System - у різних джерелах по- різному) - це служба доменних імен , що зберігає відповідності IP- адрес та імен вузлів. Фактично , коли Ви вводите в бразуер , наприклад , " myrusakov.ru " браузер не знає , до чого підключатися , і звертається до DNS-сервера , який , знаючи ім'я вузла , передає IP- адресу. Також сервер займається і зворотною операцією , тобто за IP- адресою він видає ім'я вузла. У PHP є функції для роботи з DNS , і про них ми поговоримо прямо зараз .

Впервую чергу , необхідно зрозуміти , що на одному IP- адресі може перебувати відразу багато доменних імен , тому яке саме доменне ім'я Вам , зрештою , поверне сервер , залежить тільки від нього. Вірно і зворотне твердження про те , що одному доменному імені може відповідати відразу кілька IP- адрес.

У зв'язку з цим , не завжди функції для роботи з DNS поводитимуться коректно , але все-таки знати їх корисно:

<? php

  $ ip = gethostbyname ( " vk.com " ) ;

  echo $ ip ;

  echo " <br /> " ;

  echo gethostbyaddr ($ ip ) ;

  echo " <br /> " ;

  print_r ( gethostbynameL ( " vk.com " )) ;

? >

Функція gethostbyname ( ) приймає ім'я вузла і повертає IP- адресу. А функція gethostbyaddr ( ) приймає IP -адресу та повертає ім'я вузла (ім'я сервера). Як я вже говорив , у одного імені вузла може бути багато IP- адрес , і щоб отримати список всіх IP- адрес у даного вузла , існує функція gethostbynameL ( ) . У прикладі весь масив виводиться через отладочную функцію print_r ( ) .

Таким чином , використовувати функції для роботи з DNS не складе ніяких труднощів. Використовувати ж їх можна , наприклад , для захисту від ddos - атак , коли програмно можна заблокувати всі IP- адреси зловмисників , а не 1 конкретну адресу.