命名管道有时不起作用
Named pipe sometimes doesn't work
所以我编写了一个 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;
}
}
会不会是管道设置问题之类的?我不明白为什么它几乎一直有效,但有时没有明确的原因或时间...
提前感谢您的帮助!
好的,所以我想我解决了这个问题,也许不是最好的方式,但它似乎足以满足我的目的。
在设法重现问题后,我开始考虑 Handle 可能处于打开或忙碌状态(感谢 Karsten!!)。我可以通过使用 windows powershell 和 运行 \.\pipe\name(其中名称是管道名称)来让游戏显示 121 错误。这将打开管道,游戏无法再连接,显示错误 121。
我如何 "fixed" 它:在一秒钟后没有建立连接时重新创建管道。通常在我的应用程序中,当服务器连接时,客户端已经准备就绪。所以连接应该是立即的。如果不是,现在管道会在一秒钟后重新创建,然后它就会工作。当然这不是一个干净的修复,但我不知道手柄通常如何打开,因为通常唯一尝试连接到管道的应用程序是游戏...
但无论如何,对于 30 次出现问题中的 1 次,(仍然)出于某些奇怪的原因,这是一个不错的解决方法...
如果有任何其他想法,我将不胜感激,但我认为这是目前有效的:)
所以我编写了一个 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;
}
}
会不会是管道设置问题之类的?我不明白为什么它几乎一直有效,但有时没有明确的原因或时间...
提前感谢您的帮助!
好的,所以我想我解决了这个问题,也许不是最好的方式,但它似乎足以满足我的目的。
在设法重现问题后,我开始考虑 Handle 可能处于打开或忙碌状态(感谢 Karsten!!)。我可以通过使用 windows powershell 和 运行 \.\pipe\name(其中名称是管道名称)来让游戏显示 121 错误。这将打开管道,游戏无法再连接,显示错误 121。
我如何 "fixed" 它:在一秒钟后没有建立连接时重新创建管道。通常在我的应用程序中,当服务器连接时,客户端已经准备就绪。所以连接应该是立即的。如果不是,现在管道会在一秒钟后重新创建,然后它就会工作。当然这不是一个干净的修复,但我不知道手柄通常如何打开,因为通常唯一尝试连接到管道的应用程序是游戏...
但无论如何,对于 30 次出现问题中的 1 次,(仍然)出于某些奇怪的原因,这是一个不错的解决方法...
如果有任何其他想法,我将不胜感激,但我认为这是目前有效的:)