几天来,我一直在尝试运行一个测试程序,以通过命名管道将数据从 64 位应用程序发送到 32 位应用程序。在我的 Windows 8.1 笔记本电脑(64 位)上,下面代码中的测试程序运行得非常好。当我尝试在 Windows 7(64 位)台式计算机上运行完全相同的代码时,服务器端弹出“pwrite.exe 已停止工作”。当我编译它并在桌面上运行它或者当我在台式计算机上运行可执行文件(在笔记本电脑上编译)时(只需复制两个 .exe 文件),就会发生这种情况。
奇怪的是,客户端在第一个WriteFile 操作中收到了通过命名管道发送的值,但它不会从for 循环中的第二个操作中获取值。所以客户端接收到正确的值并显示在控制台窗口后,服务器端就卡住了。可能是由于某种原因我没有写入权限并且系统在一次操作后意识到这一点,但我希望出现与权限相关的错误,但事实并非如此。
给你一个更好的主意:
笔记本电脑和台式计算机帐户都以管理员身份运行。我尝试在控制面板中将安全级别设置为最低级别。
我在桌面计算机上禁用了 Windows 防火墙
两台计算机的命令窗口中的“netstat -a”在端口 445、135 和 137 下给出“LISTENING”,据我所知这些端口通常用于命名管道。
我使用的是 Visual Studio 2012
无论是客户端还是服务端独立运行都不会出现这个问题
台式机运行频率为 3.4GHz,笔记本电脑运行频率为 1.8GHz
台式机有 .NET framework 4.0,笔记本电脑有 4.5
我认为解决方案要么在安全设置中找到,要么是异步问题,所以这是我搜索了几天的方向,但没有成功。
服务器:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include "globals.h"
using namespace std;
#define THE_PIPE "\\\\.\\pipe\\testpipe"
int main()
{
HANDLE pipe = CreateFile(THE_PIPE, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
double i = 0;
boolean r = true;
while (r == true) {
std::ostringstream ostr;
ostr << i+0.000010;
std::string theNumberString = ostr.str();
string message = theNumberString;
WriteFile(pipe, message.c_str(), message.length() + 1, NULL, NULL);
cout << GetLastError() << endl;
i++;
if (pipe == INVALID_HANDLE_VALUE)
{
cout << "Error: " << GetLastError();
}
}
return 0;
}
客户:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <conio.h>
using namespace std;
#define THE_PIPE "\\\\.\\pipe\\testpipe"
int main()
{
boolean t = true;
char key = '\0';
HANDLE pipe = CreateNamedPipe(THE_PIPE, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); //FILE_SHARE_READ
while (1) {
if (_kbhit()) key = _getch();
if (key == 'q') break;
if (pipe == INVALID_HANDLE_VALUE)
{
cout << "Error: " << GetLastError();
}
char data[1024];
DWORD numRead;
ConnectNamedPipe(pipe, NULL);
ReadFile(pipe, data, 1024, &numRead, NULL);
if (numRead > 0){
cout << data << endl;
}
}
CloseHandle(pipe);
}
最佳答案
我可以看出这里有些地方不对。
您使用 FILE_FLAG_OVERLAPPED
打开管道。您需要提供 OVERLAPPED
结构作为 WriteFile
的最后一个参数,但您传递了 NULL
。
参见 WriteFile
文档。现在正因为如此,您可能会在第二次尝试写入 ERROR_IO_PENDING
时收到错误代码。
我的建议是重构您的服务器代码,以便您可以正确地使用重叠范式,或者关闭关闭重叠标志(意味着您的lbNumberofBytesWritten
参数将必须是非 NULL)。
关于c++ - 命名管道程序在一台计算机上工作,服务器在另一台计算机上停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21171370/