почему мы не можем принять () сокет для некоторого процесса и данные recv () от его потомка? - PullRequest
2 голосов
/ 10 декабря 2011

Я пытаюсь реализовать простой веб-сервер в Linux, который подключается к клиенту (браузеру), получает некоторые запросы от клиента (например, GET), а затем отправляет ответ с нужным файлом.Я использую сокет связи.Я хочу создать пул рабочих процессов (дочерних процессов) при запуске сервера, чья работа заключается в обработке входящих запросов.Родительский процесс должен accept() принять входящий запрос и отправить свой дескриптор файла одному из рабочих процессов для его обработки и отправить ответ клиенту с запрошенным файлом.

Проблема, с которой я столкнулсяСтолкнулся с тем, что когда я accept() запрашиваю и отправляю его рабочему процессу, функции recv() или read() возвращают -1, что означает ошибку:

Операция с сокетом наsocket

Но когда я пытаюсь использовать функции recv() или read() в родительском процессе, они работают очень хорошо и возвращают количество полученных байтов.

Как я могурешить эту проблему?

PS: я использую общую память для передачи дескриптора файла из родительского процесса в рабочий процесс (дочерний процесс) и использую семафоры для управления тем, какой работникпроцесс обработает запрос


РЕДАКТИРОВАТЬ:

На самом деле, это проектное задание, и одна из спецификаций - отправить дескриптор файла черезTон поделился памятью.Однако можно ли отправить указатель на файл-дескриптор?

Ответы [ 3 ]

5 голосов
/ 10 декабря 2011

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

Что вы можете сделать, это отправить дескриптор файла через сокет домена Unix, используя sendmsg и вспомогательные данные. Это звучит немного похоже на магию (черт возьми, это - это немного похоже на магию), но оно довольно стандартно среди Unix, поэтому оно должно работать.

4 голосов
/ 10 декабря 2011

Является ли ваш работник другим процессом или просто другим потоком?Я уверен, что ваши дескрипторы не будут действительны вне процесса создания / владения ими.Это должно быть немного похоже на местные указатели.Они действительны только для процесса, который их создал (из-за адресации виртуальной памяти и прочего).

1 голос
/ 10 декабря 2011

Возможно, лучший способ - создать сокет сервера перед fork и разрешить дочерним процессам вызывать accept ().Таким образом, родительский процесс не должен доставлять принятые сокеты дочерним элементам.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...