Как передать сокет в другой процесс

Обновлено: 04.07.2024

операционная система Windows предоставляет механизмы для облегчения обмена данными и совместного использования данных между приложениями. В совокупности действия, которые поддерживаются этими механизмами, называются взаимосвязями (IPC). Некоторые формы IPC упрощают разделение труда между несколькими специализированными процессами. Другие формы IPC облегчают разделение труда между компьютерами в сети.

Как правило, приложения могут использовать IPC категории "клиенты" или "серверы". Клиент — это приложение или процесс, запрашивающий службу от какого-либо другого приложения или процесса. Сервер — это приложение или процесс, отвечающий на запрос клиента. Многие приложения действуют как клиент и сервер в зависимости от ситуации. Например, приложение для обработки текстов может выступать в качестве клиента в запросе сводной таблицы производственных затрат из приложения электронной таблицы, выступающего в качестве сервера. Приложение электронной таблицы, в свою очередь, может работать в качестве клиента при запросе последних уровней инвентаризации от приложения управления инвентаризацией.

После принятия решения о том, что приложение будет выгодным из IPC, необходимо решить, какой из доступных методов IPC использовать. Скорее всего, приложение будет использовать несколько механизмов IPC. Ответы на эти вопросы определяют, может ли приложение использовать преимущества одного или нескольких механизмов IPC.

  • Должно ли приложение взаимодействовать с другими приложениями, работающими на других компьютерах в сети, или достаточно для того, чтобы приложение могло обмениваться данными только с приложениями на локальном компьютере?
  • должно ли приложение взаимодействовать с приложениями, работающими на других компьютерах, которые могут работать под управлением разных операционных систем (например, 16-разрядные Windows или UNIX)?
  • Следует ли пользователю приложения выбрать другие приложения, с которыми взаимодействует приложение, или может ли приложение неявным образом найти своих взаимодействующих партнеров?
  • Следует ли, чтобы приложение взаимодействовало со многими различными приложениями обычным образом, например разрешить операции вырезания и вставки с любым другим приложением или должны ли требования к обмену информацией ограничиваться ограниченным набором взаимодействий с конкретными другими приложениями?
  • Является ли производительность критически важным аспектом приложения? Все механизмы IPC включают некоторый объем издержек.
  • Должно ли приложение быть приложением с графическим интерфейсом или консольным приложением? Для некоторых механизмов IPC требуется приложение с графическим пользовательским интерфейсом.

Windows поддерживает следующие механизмы IPC:

Использование буфера обмена для IPC

Буфер обмена выступает в качестве центрального депозита для совместного использования данных между приложениями. Когда пользователь выполняет операцию вырезания или копирования в приложении, приложение помещает выбранные данные в буфер обмена в одном или нескольких стандартных или определенных форматах приложения. Затем любое другое приложение может получить данные из буфера обмена, выбрав из доступных форматов, которые он понимает. Буфер обмена — это очень слабо связанный носитель Exchange, где приложения должны быть согласованы только с форматом данных. Приложения могут находиться на одном компьютере или на разных компьютерах в сети.

Ключевой момент: Все приложения должны поддерживать буфер обмена для тех форматов данных, которые они понимают. Например, текстовый редактор или текстовый процессор должен иметь по крайней мере возможность создавать и принимать данные из буфера обмена в формате чистого текста. Дополнительные сведения см. в разделе буфер обмена.

Использование COM для IPC

Приложения, использующие OLE для управления составными документами, то есть документы, состоящие из данных различных приложений. OLE предоставляет службы, облегчающие приложениям вызов в других приложениях для редактирования данных. Например, текстовый процессор, использующий OLE, может внедрить граф из электронной таблицы. Пользователь может автоматически запустить электронную таблицу с помощью текстового процессора, выбрав внедренную диаграмму для редактирования. OLE берет на себя запуск электронной таблицы и представление графа для редактирования. Когда пользователь закрывает электронную таблицу, диаграмма будет обновлена в исходном документе текстового процессора. Электронная таблица является расширением текстового процессора.

Основой OLE является объектная модель компонента (COM). Программный компонент, использующий COM, может взаимодействовать с множеством других компонентов, даже если они еще не были написаны. Компоненты взаимодействуют как объекты и клиенты. Распределенная модель COM расширяет модели программирования COM таким образом, чтобы она работала по сети.

Ключевой момент: OLE поддерживает составные документы и позволяет приложению включать внедренные или связанные данные, которые при выборе автоматически запускают другое приложение для редактирования данных. Это позволяет расширить приложение с помощью любого другого приложения, использующего OLE. Объекты COM предоставляют доступ к данным объекта через один или несколько наборов связанных функций, известных как интерфейсы. дополнительные сведения см. в разделе COM и ActiveX службы объектов.

Использование копирования данных для IPC

Ключевой момент: копирование данных можно использовать для быстрой отправки сведений в другое приложение с помощью Windows messaging. Дополнительные сведения см. в разделе копирование данных.

Использование DDE для IPC

DDE — это протокол, позволяющий приложениям обмениваться данными в различных форматах. Приложения могут использовать DDE для одноразовых обменов данными или для текущих обменов, в которых приложения обновляются по мере появления новых данных.

Форматы данных, используемые DDE, совпадают с форматами, используемыми в буфере обмена. DDE можно рассматривать как расширение механизма буфера обмена. Буфер обмена почти всегда используется для одноразового ответа на пользовательскую команду, например для выбора команды вставить в меню. DDE также обычно инициируется пользователем с помощью пользовательской команды, но часто остается без вмешательства пользователя. Кроме того, можно определить пользовательские форматы данных DDE для особого целевого IPC между приложениями с более тесно связанными требованиями к обмену данными.

Обмен DDE может происходить между приложениями, запущенными на одном компьютере, или на разных компьютерах в сети.

Ключевой момент: DDE не так эффективнее, как новые технологии. Тем не менее можно по-прежнему использовать DDE, если другие механизмы IPC не подходят или если необходимо взаимодействовать с существующим приложением, которое поддерживает только DDE. дополнительные сведения см. в разделе платформа динамических данных Exchange и платформа динамических данных библиотеки управления Exchange.

Использование сопоставления файлов для IPC

Сопоставление файлов позволяет процессу обрабатывать содержимое файла так, будто он был блоком памяти в адресном пространстве процесса. Процесс может использовать простые операции с указателями для проверки и изменения содержимого файла. Когда двум или более процессам выполняется доступ к одному сопоставлению файлов, каждый процесс получает указатель на память в своем собственном адресном пространстве, который может использоваться для чтения или изменения содержимого файла. Для предотвращения повреждения данных в многозадачной среде процессы должны использовать объект синхронизации, например семафор.

Для предоставления именованной общей памяти между процессами можно использовать особый вариант сопоставления файлов. При указании файла подкачки системы при создании объекта сопоставления файлов объект сопоставления файлов рассматривается как блок общей памяти. Другие процессы могут получить доступ к тому же блоку памяти, открыв тот же объект сопоставления файлов.

Сопоставление файлов является довольно эффективным, а также предоставляет поддерживаемые атрибуты безопасности операционной системы, которые могут помочь предотвратить несанкционированный повреждение данных. Сопоставление файлов может использоваться только между процессами на локальном компьютере. его нельзя использовать по сети.

Ключевой момент: Сопоставление файлов является эффективным способом для двух или более процессов на одном компьютере для совместного использования данных, но необходимо обеспечить синхронизацию между процессами. Дополнительные сведения см. в разделе Сопоставление файлов и Синхронизация.

Использование слота для IPC

Использование каналов для IPC

Существует два типа каналов для двусторонней связи: анонимные каналы и именованные каналы. Анонимные каналы позволяют связанным процессам передавать данные друг другу. Как правило, анонимный канал используется для перенаправления стандартного ввода или вывода дочернего процесса, чтобы он мог обмениваться данными с родительским процессом. Для обмена данными в обоих направлениях (дуплексная операция) необходимо создать два анонимных канала. Родительский процесс записывает данные в один канал, используя его маркер записи, в то время как дочерний процесс считывает данные из этого канала, используя его маркер чтения. Аналогичным образом дочерний процесс записывает данные в другой канал, а родительский процесс считывает из него. Анонимные каналы не могут использоваться по сети и не могут использоваться между несвязанными процессами.

Именованные каналы используются для обмена данными между процессами, которые не являются связанными процессами и между процессами на разных компьютерах. Как правило, серверный процесс именованного канала создает именованный канал с известным именем или именем, которое должно обмениваться с клиентами. Клиентский процесс именованного канала, который знает имя канала, может открыть его другой конец с учетом ограничений доступа, заданных процессом сервера именованных каналов. После того как сервер и клиент подключены к каналу, они могут обмениваться данными, выполняя операции чтения и записи в канале.

Ключевой момент: Анонимные каналы предоставляют эффективный способ перенаправлять стандартные входные или выходные данные в дочерние процессы на том же компьютере. Именованные каналы предоставляют простой программный интерфейс для передачи данных между двумя процессами независимо от того, находятся ли они на одном компьютере или по сети. Дополнительные сведения см. в разделе каналы.

Использование RPC для IPC

RPC позволяет приложениям вызывать функции удаленно. Таким образом, RPC делает IPC проще, чем вызов функции. RPC работает между процессами на одном компьютере или на разных компьютерах в сети.

RPC, предоставляемый Windows, соответствует требованиям к распределенным вычислительным средам (использование) Open Software Foundation (DCE). Это означает, что приложения, использующие RPC, могут взаимодействовать с приложениями, работающими с другими операционными системами, поддерживающими DCE. RPC автоматически поддерживает преобразование данных для учета различных архитектур оборудования и для упорядочения байтов между разнородными средами.

Клиенты и серверы RPC тесно связаны, но по-прежнему поддерживают высокую производительность. Система активно использует RPC для упрощения связи между клиентом и сервером между различными частями операционной системы.

Ключевой момент: RPC — это интерфейс уровня функции с поддержкой автоматического преобразования данных и взаимодействия с другими операционными системами. С помощью RPC можно создавать высокопроизводительные распределенные приложения с высоким уровнем производительности. Дополнительные сведения см. в разделе компоненты Microsoft RPC.

использование сокетов Windows для IPC

Windows Сокеты — это независимый от протокола интерфейс. В нем используются возможности связи базовых протоколов. в сокетах Windows 2 при необходимости можно использовать обработчик сокетов в качестве файла с стандартными функциями файлового ввода-вывода.

Windows Сокеты основаны на гнездах, которые впервые популярны по Berkeley Software Distribution (BSD). приложение, которое использует сокеты Windows, может взаимодействовать с другой реализацией сокета в других типах систем. Однако не все поставщики транспортных служб поддерживают все доступные варианты.

ключевой момент: Windows сокеты — это независимый от протокола интерфейс, поддерживающий текущие и новые сетевые возможности. дополнительные сведения см. в разделе сокеты Windows 2.

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

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

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

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

Создание дубликата дескриптора выглядит примерно так:

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

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

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

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

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

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

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

Создание дубликата дескриптора выглядит примерно так:

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

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

У нас есть приложение, которое создает много сокетов, которые принадлежат его потоку, по замыслу, если это приложение каким-то образом терпит неудачу, все потоки останавливаются, что не требуется. Таким образом, чтобы преодолеть эту проблему, каждый поток должен быть отделен от основного приложения, и если один из потоков выходит из строя, другие должны быть запущены. Одна вещь в нашем уме-это передать созданный сокет другому процессу java, так как же это правильно?

Приветствуется и другой подход?

Жду ваших предложений.

Я хочу запустить программу под названием VLC в java. Я создал его процесс во время выполнения. Я не знаю, как передать команды этому процессу. Также программой VLC можно управлять с помощью командной строки. Я хочу установить порт и адрес IP на VLC программы прослушивания потоковых данных. Каждый.

Раздвоение:

Насколько я могу судить, вы не можете передать дескриптор сокета между процессами Java, используя обычный API. Тем не менее, кажется, что это возможно на windows, используя Winsock 2 API . На Posix вы должны иметь возможность fork дочерний процесс с доступом к родительскому сокету, так как разветвленные процессы наследуют родительские сокеты .

Я думаю, вы могли бы реализовать новый класс SocketImpl, который поддерживает перемещение дескриптора сокета в другой процесс, но для этого вам нужно будет написать код JNI.

Звучит довольно волосато для меня, я сомневаюсь, что разветвление нового процесса изнутри Java-хорошая идея!

Слушатели:

Другой подход может заключаться в создании нового процесса 'listener', который по сути является новым предварительно разветвленным работником. Затем каждый работник мог по очереди прослушивать сокет для подключения. Затем работники должны будут координировать свои действия с процессом управления, который управляет созданием новых процессов по мере необходимости.

Я согласен с @Bozho,, если ошибка в одном потоке может уничтожить их всех (я думаю, это должно быть исключение JVM, убивающее все приложение), у вас есть большая проблема. Вы должны рассмотреть возможность изоляции потоков, если это возможно.

Это не так. (Сокеты не могут быть сериализованы.)

Или передайте всю информацию о сокете (address/port) другому приложению, которое само может открыть аналогичный сокет.

см .Этот аналогичный вопрос о передаче сокета между процессами.
К сожалению, барьер адресного пространства не может быть превышен.

Я скорее согласен с Божо, что вам нужно перепроектировать свои приложения / потоки критиков, чтобы исключение или ошибка убивали весь ваш VM.

Чтобы помочь вам в этом, я предлагаю вам взглянуть на :

    и Thread.setUncaughtExceptionHandler(. ) (см. гиперссылку ниже) , которая помогает извлекать непредвиденные проблемы (например, время выполнения)
  • Runtime.addShutdownHook(. ) (см. гиперссылку ниже) , которая помогает красиво закрывать вещи (например, когда происходит OutOfMemoryError)

У меня есть два процесса. Я запускаю первый процесс из консоли (bash). И первый процесс-это интерн, порождающий второй процесс. Второй процесс-это чтение из файла до тех пор, пока он не получит сигнал SIGINT или SIGTERM от пользователя. Но когда я нажимаю ctrl+c, программа bash передает сигнал.

Используйте класс, который совместно используется потоками для хранения сокетов. Вы можете использовать HashMap для обозначения каждого сокета, чтобы другие потоки могли ссылаться на тот, который ему нужен.

Я хочу ответить тем, кто говорит: "просто поймайте исключения и выйдите из потока".

Вы не можете поймать все исключения. Следующее приводит к выходу java jvm:

  • утверждение jvm из - за ошибок в реализации jvm
  • некоторые сбои в коде jni (sigsegv, sigabrt)
  • OutOfMemory

Похожие вопросы:

В Linux, возможно ли для меня открыть сокет и передать сокет другому процессу? Если да, то не могли бы вы сказать мне, где я могу найти пример? Спасибо.

Мне нужно запустить bin/psql в командной строке (или скрипте) и распечатать его pg_backend_pid , чтобы pg_backend_pid можно было передать другому процессу (запускаемому root) в качестве аргумента.

Я хочу передать сокет SSL (вместе с его сеансом SSL) другому процессу. Возможно ли это ? В реализации сокета, отличного от SSL, я использую WSADuplicateSocket (Windows API), чтобы получить.

Я хочу запустить программу под названием VLC в java. Я создал его процесс во время выполнения. Я не знаю, как передать команды этому процессу. Также программой VLC можно управлять с помощью.

У меня есть два процесса. Я запускаю первый процесс из консоли (bash). И первый процесс-это интерн, порождающий второй процесс. Второй процесс-это чтение из файла до тех пор, пока он не получит.

Глядя на синтаксис сигнала, я вижу, что он не дает гибкости передачи сигнала другому pid (pid_t). процесс может только игнорировать, делать по умолчанию или настраивать действие на себя. каковы.

Я читал, что вы можете передать файловый дескриптор другому процессу , который кажется идеальным для того, что я хочу. Есть ли шанс, что это вообще возможно в Haskell ? Чтобы быть ясным, я не.

Передать указатель на объект в новый поток
Добрый день. Нужно сделать типо показа времени на компьютере в форме, которое будет обновляться.


Передать параметр по ссылке в новый поток (REF)
Доброго времени суток, нужен аналог передачи параметра по ссылке при инициализации нового потока.

Как передать аргументы в поток?
Здравствуйте, как ни стараюсь разобраться, никак не получается. Помогите пожалуйста. main.cpp .

Как передать событие в поток
Подскажите как в уже рабочий поток передать событие (значение count) без глобальных переменных ? И.

Я мало что понял из текста, но вообще из одного потока в другой можно передавать адрес объекта,
существующего в 1-м потоке. Например, я передаю адрес объекта типа QImage и он там обрабатывается.

Возможно, что дело в QTcpSocket. Он так же является объектом и может иметь родителя и поток. Поместив указатель на объект QTcpSocket в объект SendDataWorker и перенеся объект SendDataWorker в отдельный поток вы не переносите автоматически объект QTcpSocket в тот же самый поток. Дальнейшие попытки использовать QTcpSocket внутри SendDataWorker в рамках отдельного потока и приводят к ошибкам, наверное.

Добавлено через 7 минут
Хотя, если подумать, то автор так и говорит в названии темы
Сделать ему так же moveToThread, не вариант?

Добавлено через 21 минуту
Думаю, что Ygg, прав. Нужно поместить и класс в поток и сам сокет..

Для тех у кого такая же проблема будет, вообщем у QTcpSocket есть метод socketDescriptor(), который возвращает сокет, его то и можно использовать в разных потока при помощи создания новых объектов QTcpSocket.
Псевдокод:

Как передать параметр в поток
Здравтсвуйте, есть функция, принмающая строку и хочу, чтобы она заработала в новом потоке - как.


Как передать параметр в поток
Мне надо передать ListView1.SelectedItems(0).SubItems.Item(2).Text в новый поток, как это.

Как передать функцию в поток
Имеется стандартный пример пример создания потока в C++Builder Unit2: .

Как передать указатель в поток?
Есть GUI прога, в главном классе создаётся объект потока. Вопрос: как передать этому потоку.

Читайте также: