Я активировал код, который, как я уверен, работал несколько месяцев назад. Это сводит меня с ума, но это уже не так. Я не мог найти ответа в других вопросах.Именованная труба: ReadFile после возврата ConnectNamedPipe ERROR_BROKEN_PIPE
На стороне сервера я создаю трубу с помощью
#define MAX_MESSAGE_LENGTH 1024
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, static_cast<PACL>(0), FALSE);
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
auto pipe_name = _T("\\\\.\\pipe\\") + _serviceName;
HANDLE pipe = CreateNamedPipe(
pipe_name.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
MAX_MESSAGE_LENGTH, MAX_MESSAGE_LENGTH, // buffer lengths (advisory)
0, // default timeout of 50ms when WaitNamedPipe uses NMPWAIT_USE_DEFAULT_WAIT
&sa));
Затем поток ожидает для входящих клиентов с ConnectNamedPipe
. ConnectNamedPipe
блоки до тех пор, пока клиент не соединяется с
HANDLE pipe = CreateFile(
pipe_name.c_str(), // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_ATTRIBUTE_NORMAL, // default attributes
NULL); // no template file
ConnectNamedPipe
на сервере, то возвращается с TRUE
и GetLastError == 0
. Но когда он пытается позвонить ReadFile
, чтобы читать входящие данные на трубе, ReadFile
немедленно возвращает FALSE
и GetLastError==ERROR_BROKEN_PIPE
. На стороне клиента CreateFile
вернул GetLastError==231
, «Все экземпляры труб заняты». Хотя это единственный клиент! Вызов WaitNamedPipe(pipe, 2000)
возвращается с кодом ошибки 121, «Срок таймаута семафора истек». Увеличение количества разрешенных клиентов в CreateNamedPipe
ничего не меняет.
Кажется, что труба полностью сломана в момент, когда клиент пытается подключиться. Но почему? Оба клиента и сервер работают на одном компьютере с одним и тем же пользователем и даже с тем же сеансом. Еще один вызов ConnectNamedPipe
, а затем с GLE = 232: «Труба закрыта».
У меня также были другие SECURITY_ATTRIBUTES
для CreateNamedPipe
, которые должны позволять пользователям не приподнятым пользователям подключаться, но это не имеет значения.
Также я попытался использовать CallNamedPipe
на клиенте с тем же результатом.
Просьба указать [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve), показывающий, как вы используете трубку на обоих концах. –
Я предполагаю, что у вас есть какая-то программа-изгоев, которая подключается к вашей трубе и затем закрывается. Вы можете попробовать изменить название трубы и посмотреть, что-нибудь изменится. Если это не удается, я рекомендую использовать [Process Monitor] (https://technet.microsoft.com/en-us/sysinternals/bb896645), чтобы найти причину. – rodrigo
Если предположение Родриго правильное (и это кажется хорошим), возможно, стоит попробовать GetNamedPipeClientProcessId() на сервере сразу же после успешного завершения ConnectNamedPipe(). –