Регистрация Главная Сообщество
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Ответ
 
Опции темы
Старый 06.12.2010, 16:33   #1
 Разведчик
Аватар для Tem1q
 
Tem1q на правильном пути
Регистрация: 24.08.2010
Сообщений: 12
Популярность: 26
Сказал(а) спасибо: 5
Поблагодарили 8 раз(а) в 5 сообщениях
 
По умолчанию Передача сокетов между процессами

Авторы: Warren Young и Frank Schmied

Для того, чтобы передать сокет от одного процесса другому, можно воспользоваться функцией WSADuplicateSocket() из Winsock 2. Изначально в часто задаваемых вопросах (FAQ) эту проблему решали следующим способом:

Спецификация данного метода подробно описывается в секции 2.10 MSDN-а, где подробно по шагам комментируется данная функция. Так же можно почитать статью Q150523 в Microsoft Knowledge Base, в которой описываются различия наследования сокета в разных версиях Windows.

Другая забавная особенность Win32 API заключается в том, что он позволяет присваивать новому процессу (во время его создания) различные "стандартные обработчики" ("standard handles") (stdin, stdout и stderr). Статья Q190351 в MSKB описывает данный момент. Обратите внимание, что данная возможность доступна только для дочерних процессов; т.е. Вы не сможете перенаправить стандартный обработчик I/O на сокет. Естевственно, что данная возможность не предоставляет нам таких преимуществ, как, например, Unix-функция dup2().

Так же в FAQ сказано, что мы не можем использовать такую возможность в Winsock 1.1. Однако Frank Schmied показал, что можно слегка обмануть стек Microsoft Winsock 1.1 в Win32, и в конечном результате добиться своей цели. Вот его комментарии:

Можно заставить Winsock 1.1 передавать сокет от одного процесса другому используя Win32 функцию DuplicateHandle(). Обработка данного вызова может быть весьма сложной. Фактически, генерация реальных дескрипторов процесса не так проста, как может показаться на первый взгляд. Windows использует два типа дескрипторов окна: псевдо-дескрипторы и реальные дескрипторы. Обычно дескрипторы в Windows - это адреса в памяти, и экземпляр дескриптора является ни чем иным как смещением указателя на код, расположенный в текущем адресном пространстве. Итак, дескриптор процесса HINSTANCE (псевдо или локальный) обычно равен 0x4000000. Передача данного дескриптора от одного процесса к другому не работает. Чтобы получить реальный дескриптор текущего процесса, можно использовать OpenProcess():

Код:
    OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
Создание дубликата дескриптора выглядит примерно так:

Код:
 SOCKET ConvertProcessSocket(SOCKET oldsocket, DWORD source_pid)
               {
                   HANDLE source_handle = OpenProcess(PROCESS_ALL_ACCESS,
                           FALSE, source_pid);
                   HANDLE newhandle;
                   DuplicateHandle(source_handle, (HANDLE)oldsocket,
                           GetCurrentProcess(), &newhandle, 0, FALSE,
                           DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
                   CloseHandle(source_handle);
                   return (SOCKET)newhandle;
               }
Данный пример отлично работает на многопроцессорном вебсервере. Данная функция передаёт сокет в новый процесс и закрывает дескриптор старого процесса. Дескриптор имеет те же свойства что и старый, но не может быть унаследован дочерним процессом. Чтобы исправить это, достаточно в DuplicateHandle() изменить FALSE на TRUE. Как мы видим, дескриптор основного процесса может быть псевдо-дескриптором, но дескриптор второго процесса обязан быть реальным.

Алгоритм таков: исходный процесс конвертирует локальный дескриптор SOCKET в реальный дескриптор при помощи OpenProcess(), затем передаёт это значение и ID процесса другому процессу. Второй процесс вызывает функцию ConvertProcessSocket(), чтобы преобразовать реальный дескриптор в локальный, который уже можно будет использовать в Winsock. Обратите внимание, что вызов DuplicateHandle() закрывает дескриптор первого процесса, а затем функция CloseHandle() закрывает реальный дескриптор, который вы передаёте второму процессу.

Недостатки: данная методика скорее всего работает только со стеком Microsoft. Однозначно не будет работать в Win16, и, возможно в WinCE. Не извесно, будет или нет работать в присутствие Layered Service Providers, исключая Windows NT 4.0 SP 4+, в которой пропатчен уровень Installable FileSystems (IFS). Возможно найдутся ещё причины, по которым данный метод может не сработать
  Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача между аккаунтами lvlaksim Архив 3 28.07.2009 23:03
Передача между расами DR.ThRaX Rising Force Online 2 28.10.2008 19:59
передача между расами extrim92 Архив уязвимостей 1 04.06.2008 22:13

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 14:05.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net