ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
 
 
Опции темы Поиск в этой теме Опции просмотра

УЧИМСЯ ИСПОЛЬЗОВАТЬ WINSOCK. ЧАСТЬ I.
  #1  
Старый 05.06.2009, 00:14
Аватар для slesh
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию УЧИМСЯ ИСПОЛЬЗОВАТЬ WINSOCK. ЧАСТЬ I.

УЧИМСЯ ИСПОЛЬЗОВАТЬ WINSOCK. ЧАСТЬ I.


ПРЕДИСЛОВИЕ
Статья будет состоять их 4-х частей.
1) сокеты, их создание и настройка.
2) подключение, передача и прием данных. многопоточность.
3) различного рода функции для работы с сокетами (снифанье итд итп.)
4) примеры работы с сокетами и некоторыми прикладными протоколами типа HTTP и SOCKS 5

ВВЕДЕНИЕ
Статья пригодится в первую очередь новичкам, ну и другим тоже иногда будет полезно знать некоторые вещи.
Очень часто видно на форуме, что даже для примитивной работы с сетью многие использую компоненты типа Indy и им подобные. Вот и хотелось исходя из этого, описать основные принципы работы с сокетами. Я не буду описывать работу со всеми функциями, а также работу с сокетами в не блокирующем режиме, потому как это уже не относится к основной работе. Все примеры буду приводить на Delphi потому как многим это понятнее.

ПРИНЦИПЫ РАБОТЫ
За основу работы берутся 2 DLL
wsock32.dll – устаревший вариант применяемый в Win 9x системах. (Winsock)
ws2_32.dll – более новые вариант с добавлением множества новых функций, применяется в Win NT системах. (Winsock 2)
Разница между этими библиотеками лишь в наборе функций и работе некоторых отдельных функций.

В независимости от используемой версии библиотеки можно выделить следующие ступени алгоритма работы
1) Инициализация библиотеки сокетов
2) Создание сокета
3) Настройка сокета
4) Исходящее соединение или ожидание входящего подключение.
5) Передача данных
6) Закрытие соединения.
7) Прекращение работы с библиотекой сокетов (по желанию)

Каждый из этих этапов имеет определенный набор основных команд, а также их последовательностей.

ИНИЦИАЛИЗАЦИЯ БИБЛИОТЕКИ СОКЕТОВ
Без инициализации невозможно будет работать со всеми функциями, которые напрямую зависят от сети.
Для инициализации достаточно выполнить одну лишь функцию WSAStartup
function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; stdcall;
Первым параметром задается версия библиотеки. Для старых версий задавалось $101. Для новой версии (Winsock2) используется число $202. В дальнейшем будем использовать только Winsock2 т.к. его использовании более актуально для других языков типа С++
Вторым параметром передается структура TWSAData (WSAData) в которую будет записана некоторая информация о библиотеке.
Исходя из этого инициализация библиотеки будет выглядеть как:
Код:
uses winsock2;
var
  ws: TWSAData;
begin
  WSAStartup($202,ws);
При удачной инициализации WSAStartup вернет значение = 0. Мы его проверять не будет, потому как в настоящее время это не требуется, но для надежности можно вставить проверку:
Код:
uses winsock2;
var
  ws: TWSAData;
begin
  if WSAStartup($202,ws)<>0 then
    begin
      вывод сообщения об ошибке
      exit;
    end;
СОЗДАНИЕ СОКЕТА
Для создания сокета следует использовать функцию socket.
function socket( const af, struct, protocol: Integer ): TSocket; stdcall;
Первый параметр – тип адреса, существует множество типов, но т.к. мы работает с TCP/IP то будем использовать AF_INET
Второй параметр – тип создаваемого сокета. Нас будут интересовать 3 типа
SOCK_STREAM – потоковый, с установление соединения. Используется для TCP протокола.
SOCK_DGRAM – дейтаграмный, без установки соединения. Исполь для UDP протокола.
SOCK_RAW- сырой сокет. Без заранее определенного протокола.
Третий параметр – непосредственно протокол который мы будет использовать.
Для нас будут важны следующие 3:
IPPROTO_TCP – TCP соединение
IPPROTO_UDP – UDP соединение
IPPROTO_RAW – для сырого сокета.
В результате выполнения функции мы получит дискриптор сокета, который мы будет использовать в дальнейшем для передачи информации. При ошибке, будет вернут код INVALID_SOCKET.
Код:
var
 TCP_sock:TSocket; 
 UDP_sock:TSocket;
 RAW_sock:TSocket;
begin
 TCP_sock:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // создадим TCP сокет
 if TCP_sock= INVALID_SOCKET then ошибка_создания_сокета
 UDP_sock:=socket(AF_INET, SOCK_ DGRAM, IPPROTO_ UDP); // создадим UDP сокет
 if UDP _sock= INVALID_SOCKET then ошибка_создания_сокета
 RAW_sock:=socket(AF_INET, SOCK_ RAW, IPPROTO_ RAW); // создадим сырой сокет
 if RAW_sock= INVALID_SOCKET then ошибка_создания_сокета
НАСТРОЙКА СОКЕТА
Для того чтобы куда-то подключиться или начать ожидание входящего подключения на определенном порту, необходимо настроить сокет на этот адрес и порт. Для этой цели служит структура sockaddr_in.
Для ожидания сходящего подключения необходимо заполнить следующие поля:
Тип адреса: sin_family:=AF_INET;
Порт на который будем жать подключения sin_port:=htons(SERVER_PORT);
Порт – это число в диапазоне от 0 до 65535. К примеру HTTP по умолчанию имеет порт 80.
Если задать его больше, то значением будет число = остатку от деления указанного порта на 65536. т.е. если задать PORT = 70000, то на самом деле будет = 4464;
htons – функция winsock которая преобразует номер порта в нужный для работы формат и обрезает часть, которая выходит за пределы диапазона 0-65535.
Здание IP адреса интерфейса с которого будут приниматься подключения. Это связанно с тем, что на одном компьютере может существовать несколько сетевых адаптеров и есть необходимость в привязке к какому-нибудь именно одному адресу.
Для преобразования IP адреса в нужный вид применяется функция inet_addr. Она преобразует адрес из сивольного вида в числовой (двоичный)
Для того чтобы принимать подключения со всех адаптером, можно использовать константу INADDR_ANY.
sin_addr.s_addr:=inet_addr(‘192.168.2.1’); // принимать подключения только с адреса 192.167.2.1
sin_addr.s_addr:=INADDR_ANY; // принимать со всех интерфейсов.
!ВАЖНО: следует указывать ТОЛЬКО IP адреса. Доменные имена не принимаются. По этому необходимо через DNS узнать адрес соответствующий данному имения. Об этом я расскажу чуть ниже.

Для подключения к другому компьютеру необходимо заполнить эту структуру следующим образом.
sin_family:=AF_INET; // аналогично входящему подключению
sin_port:=htons(PORT); // аналогично входящему подключению, но тут PORT указывает номер порта на который требуется подключиться.
sin_addr.s_addr:=inet_addr(‘192.168.2.1’); // указываем IP адрес куда нам необходимо подключиться.
При работе с UDP иногда требуется отослать широковещательный пакет. т.е. всем компьютерам сети. Для этого необходимо указать адрес - INADDR_BROADCAST, но для этого требуется еще указать отдельные опции для сокета.
Чаще всего мы не знаем IP адрес сервера, зато мы знаем его доменное имя.
Для поиска IP адреса по его доменному имени существует функция gethostbyname,
которая в качестве параметра принимает доменное имя. Чтобы не замарачиваться с этим делом, можно вынести это всё в отдельную функцию, которая принимает доменное имя и возвращает его IP адрес или пустое значение в случае ошибки или неверного указания доменного имени.
Код:
function GetIPAddress(name: string):string;
var
  p: PHostEnt;
begin
 p:=gethostbyname(pchar(name)); // получим IP
 if p=nil then result:=’’ // если ошибка или нет адреса
  else result:=inet_ntoa(PInAddr(p.h_addr_list^)^); // извлечем и преобразуем адрес.
end;
Также немало важным является настройка некоторых таймаутов. В частности на чтение данных из сокета. Это очень заметно при работе с UDP протоколом, где данные отправляются без установки соединения. А также в других программах, где необходимо ограничить время ожидания приема данных.
Специально для этого создана функция setsockopt. В её возможности входит очень много функций, но нам будет интересна только SOL_SOCKET с параметрами
SO_RCVTIMEO – таймаут для чтения данных
SO_SNDTIMEO – таймаут для посылки данных
Примером работы может быть следующий код
Код:
var
 timeout:TTimeVal;
begin
 timeout.tv_usec:=0;
 timeout.tv_sec:=10000; // время задается в миллисекундах. 10000 = 10 секунд
 // установим для сокета sock время ожидания чтения данных = 10 секунд.
 setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, @timeout, sizeof(ttimeval));
Важно отметить что эта опция появилась только в NT'шных ОС начиная с 2000 вроде (точно незнаю). Т.к. в winsock 1.0 не полностью были реализованы BSD сокеты, то там ата функция не поддерживается. т.е. её применение не даст ни какого эффекта.
В большинстве книг по Winsock именно про этот момент многие забывают упомянуть. На практике в многопоточных системах с большим кол-вом клиентов очень часто появляются ошибки связанные с зависшим ожиданием получения данных, что со временем очень сказывается на производительности и занимаемых ресурсах.
Для UDP – это вообще очень серьёзная вещь, потому что из-за проблем с сетью или ошибки в адресах, может всё зависать.

Также для отправки широковещательного UDP пакета, сокету необходимо установить опции SOL_SOCKET с параметром SO_BROADCAST и флагом TRUE.

Код:
var
 Opt:BOOL;
begin
  Opt:=TRUE;
  setsockopt(sock,SOL_SOCKET,SO_BROADCAST, pchar(@Opt),sizeof(Opt)) ;
Вот так вот практически не на чем заканчивается первая часть этой статьи.
Во второй части будут описаны функции подключения и принятие входящих подключения, посылка и прием данных, а также организация многопоточной обработки входящих подключений.

(С) SLESH 2009


P.S. в виду сессии, продолжение выйдет гдето через неделю.

Последний раз редактировалось slesh; 14.06.2009 в 14:06..
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Учимся юзать Мeterpreter (Или Metasploit Framework часть 4) -=lebed=- Авторские статьи 6 07.08.2007 13:27
Учимся юзать консоль MSF 3.0 beta 3 (или Metasploit Framework часть 3) -=lebed=- Авторские статьи 37 02.04.2007 17:40
SQL инъекция и Oracle, часть 2 k00p3r Чужие Статьи 0 13.06.2005 11:24
Sql инъекция и Oracle, часть первая k00p3r Чужие Статьи 0 13.06.2005 11:23



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ