- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经编写了一个类来处理命名管道连接,如果我创建了一个实例,关闭它,然后尝试创建另一个实例,调用 CreateFile()
返回 INVALID_HANDLE_VALUE
,并且 GetLastError()
返回 ERROR_PIPE_BUSY
。这里发生了什么?我该怎么做才能确保对 Connect()
的调用成功?
PipeAsync A, B;
A.Connect("\\\\.\\pipe\\test",5000);
A.Close();
cout << GetLastError(); // some random value
B.Connect("\\\\.\\pipe\\test",5000);
cout << GetLastError(); // 231 (ERROR_PIPE_BUSY)
B.Close();
这是我对 Connect()
和 Close()
的实现
BOOL PipeAsync::Connect(LPCSTR pszPipeName, DWORD dwTimeout)
{
this->pszPipeName = pszPipeName;
this->fExisting = TRUE;
DWORD dwMode = this->fMessageMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE;
hPipe = CreateFile(
this->pszPipeName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if( INVALID_HANDLE_VALUE == hPipe )
return FALSE; /* set break point here ; breaks here on second call to Connect() */
if( GetLastError() == ERROR_PIPE_BUSY )
if(!WaitNamedPipe( this->pszPipeName, dwTimeout ))
return FALSE; /* set break point here */
if( !SetNamedPipeHandleState( hPipe, &dwMode, NULL, NULL ) )
return FALSE; /* set break point here */
return TRUE;
}
VOID PipeAsync::Close()
{
if( fExisting )
DisconnectNamedPipe( hPipe );
CloseHandle( hPipe );
}
编辑: 我忘了告诉您我是如何得出结论的...我设置了注释中指示的断点。运行时,它会在第一个断点处停止。
编辑:这是我更新的代码
if( INVALID_HANDLE_VALUE == hPipe )
if( GetLastError() == ERROR_PIPE_BUSY )
{
if(!WaitNamedPipe( this->pszPipeName, dwTimeout ))
return FALSE; /* break-point: breaks here on second call */
}
else
return FALSE; /* break-point /*
现在,WaitNamedPipe()
在第二次调用 Connect()
时返回 false,而 GetLastError()
返回 2,或者 ERROR_FILE_NOT_FOUND
?
最佳答案
来自 Named Pipe Client :
If the pipe exists but all of its instances are busy, CreateFile returns INVALID_HANDLE_VALUE and the GetLastError function returns ERROR_PIPE_BUSY. When this happens, the named pipe client uses the WaitNamedPipe function to wait for an instance of the named pipe to become available.
该链接包含处理 ERROR_PIPE_BUSY
的示例代码。
编辑:
演示在命名管道上接受和连接的小型可编译示例:
const char* const PIPE_NAME = "\\\\.\\pipe\\test";
const int MAX_CONNECTIONS = 10;
void client_main()
{
DWORD last_error;
unsigned int elapsed_seconds = 0;
const unsigned int timeout_seconds = 5;
HANDLE handle = CreateFile(PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
while (INVALID_HANDLE_VALUE == handle &&
elapsed_seconds < timeout_seconds)
{
last_error = GetLastError();
if (last_error != ERROR_PIPE_BUSY)
{
break;
}
Sleep(1 * 1000);
elapsed_seconds++;
handle = CreateFile(PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
}
if (INVALID_HANDLE_VALUE == handle)
{
std::cerr << "Failed to connect to pipe " << PIPE_NAME <<
": last_error=" << last_error << "\n";
}
else
{
std::cout << "Connected to pipe " << PIPE_NAME << "\n";
CloseHandle(handle);
}
}
HANDLE _get_server_handle()
{
// Error handling omitted for security descriptor creation.
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, static_cast<PACL>(0), FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
// Create a bi-directional message pipe.
HANDLE handle = CreateNamedPipe(PIPE_NAME,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |
PIPE_READMODE_MESSAGE |
PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES,
4096,
4096,
0,
&sa);
if (INVALID_HANDLE_VALUE == handle)
{
std::cerr << "Failed to create named pipe handle: last_error=" <<
GetLastError() << "\n";
}
return handle;
}
void server_main()
{
HANDLE handle = _get_server_handle();
if (INVALID_HANDLE_VALUE != handle)
{
int count = 0;
while (count < MAX_CONNECTIONS)
{
BOOL result = ConnectNamedPipe(handle, 0);
const DWORD last_error = GetLastError();
if (ERROR_NO_DATA == last_error)
{
count++;
std::cout << "A client connected and disconnected: count=" <<
count << "\n";
CloseHandle(handle);
handle = _get_server_handle();
}
else if (ERROR_PIPE_CONNECTED == last_error)
{
count++;
std::cout << "A client connected before call to " <<
"ConnectNamedPipe(): count=" << count << "\n";
CloseHandle(handle);
handle = _get_server_handle();
}
else if (ERROR_PIPE_LISTENING != last_error)
{
std::cerr << "Failed to wait for connection: last_error=" <<
GetLastError() << "\n";
CloseHandle(handle);
break;
}
Sleep(100);
}
}
}
int main(int a_argc, char** a_argv)
{
if (2 == a_argc)
{
if (std::string("client") == *(a_argv + 1))
{
for (int i = 0; i < MAX_CONNECTIONS; i++)
{
client_main();
}
}
else if (std::string("server") == *(a_argv + 1))
{
server_main();
}
}
return 0;
}
首先执行服务器端:
pipetest.exe server
然后在客户端执行:
pipetest.exe client
我无法从发布的代码中判断出问题所在。希望这个小例子能帮助您找到问题所在。
关于c++ - 命名管道 CreateFile() 返回 INVALID_HANDLE_VALUE,GetLastError() 返回 ERROR_PIPE_BUSY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8529193/
所以我将这些东西从 C++ 移植到 C#。它的一部分看起来像这样: m_hParstat = CreateFile( _T("\\\\.\\LPTSTAT1"), GENERIC_READ
我正在使用“CreateRemoteThread & WriteProcessMemory”技术将我的 dll 注入(inject)另一个进程。我的代码在 Windows 7,8 上运行良好,但是 W
此代码在 64 位应用程序中运行。目标应用程序是 32 位的。 每次运行此代码时,CreateToolhelp32Snapshot() 都会返回 INVALID_HANDLE_VALUE,然后 Get
对于我在论坛上的第一篇帖子,因为我是一个真正的初学者,所以我看不出我的错误从何而来。在用户选择文件夹中的多个文件后,我尝试将它们重命名为“image_1.jpg”、“image_2.jpg”等...我
以下代码用于使用Delphi 2007编译: constructor TMyFile.Create(const _Filename: string); begin inherited Create
考虑: void main() { LPSTR FileName; FileName = "C:\\test2.wav"; hFile = CreateFile((LPCWST
我正在使用 CreateFileA,我第一次调用它时,它按预期工作。但是当我第二次调用它时,它返回句柄 INVALID_HANDLE_VALUE。可能是什么问题呢?仅供引用,每次我需要检查我的 USB
更新 - 已解决并回答,有问题的行已被注释掉 简要说明 即使我对 CreateFile 使用(GENERIC_WRITE 或 GENERIC_WRITE),对 CreateFileMapping 使用
为什么 HANDLE mutexHandle = INVALID_HANDLE_VALUE; WaitForSingleObject(mutexHandle, INFINITE); 阻止?它不会返回错
我和一位程序员同事进行了一场小辩论。他在他的代码中使用了以下习语: HWND hWnd = SomeFunctionWhichReturnsAWindow(); if(hWnd != NULL &&
有一个简短的例子: WIN32_FIND_DATA fd; HANDLE h = FindFirstFile(L"C:", &fd); if (h == INVALID_HANDLE_VALUE) {
我正在使用 CreateFile() 打开一个串口.我有一个测试用例(太复杂而无法重新分发),它始终导致 CreateFile()返回 INVALID_HANDLE_VALUE和 GetLastErr
我已经编写了一个类来处理命名管道连接,如果我创建了一个实例,关闭它,然后尝试创建另一个实例,调用 CreateFile() 返回 INVALID_HANDLE_VALUE,并且 GetLastErro
编辑 我似乎又向前迈进了一步。我忘记提及这是我正在处理的目录。我需要将 FILE_FLAG_BACKUP_SEMANTICS 传递给 CreateFile。不幸的是,我遇到了另一个障碍... GetF
我在 Windows 8 上的打印机过滤器环境中使用 CreateFile 打开一个文件。代码实际上是直接的 C,即使过滤器是用 C++ 构建的。 CreateFile 返回 INVALID_HAND
我在MSDN上搜索了一下 HANDLE WINAPI CreateFile( _In_ LPCTSTR lpFileName, _In_ DWORD
我正在打开一个端口与设备通信并控制设备,但是 CreateFile() 函数返回 INVALID_HANDLE_VALUE。 GetLastError() 返回 2,这意味着它找不到指定的文件。 我的
我是一名优秀的程序员,十分优秀!