2016-06-02 3 views
2

Итак, я написал приложение 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; 
      } 
     } 

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

Спасибо за любую помощь заранее!

+0

Таким образом, в случае ошибки, труба занята, а тайм-аут 'WaitNamedPipe' - через 5 секунд? Или это ошибка 121 из 'CreateFile'? –

+0

Да, ошибка произошла внутри этого оператора if на клиенте: if (! WaitNamedPipe (FULL_PIPE_NAME, 5000)) –

+1

Это происходит сразу после перезапуска клиента? Может быть, есть еще какой-то несуществующий процесс, держа ручку открытой. –

ответ

-1

Хорошо, я думаю, что я исправил проблему, возможно, не лучшим образом, но, похоже, она работает достаточно хорошо для моей цели.

После управления воспроизведением проблемы я начал работать с идеей о том, что Handle может быть открытой или занятой (спасибо Karsten !!). Я мог бы обмануть игру, указав ошибку 121, используя windows powershell и запустив \. \ Pipe \ name (где name - имя для труб). Это откроет трубу, и игра больше не сможет подключиться, показывая ошибку 121.

Как я «исправил» это: воссоздание трубы, когда соединение не производится через секунду. Обычно в моем приложении, когда сервер подключен, клиент уже готов. Поэтому соединение должно быть немедленно. Когда это не так, теперь труба воссоздается через секунду, а затем она будет работать. Вне курса это не чистое исправление, но я понятия не имею, как обычно открывается ручка, потому что обычно единственное приложение, пытающееся подключиться к трубе, - это игра ...

Но все равно это достойная работа -around для 1 в 30 раз возникла проблема для (еще) какой-то странной причине ...

Любые другие идеи будут оценены, но это работает сейчас я думаю :)