Итак, я написал приложение C++, которое соединяется с игрой Unreal Engine 4 через именованный канал. 95% времени он отлично работает, но иногда он не кажется правильно подключенным. Это очень случайно, поэтому мне трудно найти проблему, которая вызывает это. Сервер создан в моем приложении, и Клиент создается в игре UE4. И иногда игра UE4 не связывает и выводит ошибки 121:Именованная труба иногда не работает
//
// MessageId: ERROR_SEM_TIMEOUT
//
// MessageText:
//
// The semaphore timeout period has expired.
//
#define ERROR_SEM_TIMEOUT 121L
Как я сказал, что проблема возникает очень случайно, и я не могу найти конкретную причину, которая может вызвать проблемы. Труба успешно создана, я вижу это в windows powershell (get-childitem \. \ Pipe).
Я думал, может быть, у него есть что-то делать с настройками труб, которые я использую?
Это мой код для создания сервера трубы:
DWORD erPipeServer::CreatePipeServer() {
// create a SECURITY_ATTRIBUTES structure.
if (!CreatePipeSecurity(&pSa))
{
dwError = GetLastError();
//wprintf(L"CreatePipeSecurity failed w/err 0x%08lx\n", dwError);
Cleanup();
return dwError;
}
// Create the named pipe.
hNamedPipe = CreateNamedPipe(
pipename, // Pipe name.
PIPE_ACCESS_DUPLEX, // The pipe is duplex; both server and
// client processes can read from and
// write to the pipe
PIPE_TYPE_MESSAGE | // Message type pipe
PIPE_READMODE_MESSAGE | // Message-read mode
PIPE_NOWAIT, // Blocking mode is enabled
PIPE_UNLIMITED_INSTANCES, // Max. instances
BUFFER_SIZE, // Output buffer size in bytes
BUFFER_SIZE, // Input buffer size in bytes
NMPWAIT_WAIT_FOREVER, // Time-out interval
pSa // Security attributes
);
if (hNamedPipe == INVALID_HANDLE_VALUE)
{
dwError = GetLastError();
//wprintf(L"Unable to create named pipe w/err 0x%08lx\n", dwError);
Cleanup();
return dwError;
}
//wprintf(L"The named pipe (%s) is created.\n", pipename);
return dwError;
}
И это мой код для создания клиента в Unreal Engine 4:
// Try to open the named pipe identified by the pipe name.
while (true)
{
hPipe = CreateFile(
FULL_PIPE_NAME, // Pipe name
GENERIC_READ | GENERIC_WRITE, // Read and write access
0, // No sharing
NULL, // Default security attributes
OPEN_ALWAYS, // Opens existing pipe
0, // Default attributes
NULL // No template file
);
// If the pipe handle is opened successfully ...
if (hPipe != INVALID_HANDLE_VALUE)
{
GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Green, FString::Printf(TEXT("The named pipe %d is connected."), FULL_PIPE_NAME));
break;
}
dwError = GetLastError();
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (ERROR_PIPE_BUSY != dwError)
{
GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Red, FString::Printf(TEXT("Unable to open named pipe ------ %d"),dwError));
goto Cleanup;
}
// All pipe instances are busy, so wait for 5 seconds.
if (!WaitNamedPipe(FULL_PIPE_NAME, 5000))
{
dwError = GetLastError();
GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Red, FString::Printf(TEXT("Could not open pipe: 5 second wait timed out. %d"),dwError));
**THE 121 ERROR OCCURED HERE^^**
goto Cleanup;
}
}
Может быть проблема с трубой настройки или что-то еще? Я не понимаю, почему он работает почти все время, но иногда не без ясной причины, почему или когда ...
Спасибо за любую помощь заранее!
Таким образом, в случае ошибки, труба занята, а тайм-аут 'WaitNamedPipe' - через 5 секунд? Или это ошибка 121 из 'CreateFile'? –
Да, ошибка произошла внутри этого оператора if на клиенте: if (! WaitNamedPipe (FULL_PIPE_NAME, 5000)) –
Это происходит сразу после перезапуска клиента? Может быть, есть еще какой-то несуществующий процесс, держа ручку открытой. –