记录error:在进行一个项目的时候利用管道传输数据,当一端异常退出后重新启动时报错,如下代码:
客户端:
//打开可用的命名管道,并与服务器端进行进程间通信
hPipe = CreateFileA(
EXAMP_PIPE,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH,
NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
cout << "open read pipe error" << GetLastError() << endl;
return 0;
}
else {
while(1){
//向服务端发送数据
cout << "please input the path:" << endl;
char szBuffer[BUF_SIZE] = { 0 };
//getline(szBuffer,BUF_SIZE);
cin >> szBuffer;
ast = WriteFile(hPipe, szBuffer, BUF_SIZE, &cb_write, NULL);
if (!ast) {
cout << "write Failed !!error number:" << GetLastError() << endl;
break;
}
else {
cout << "write success" << endl;
}
}
}
服务端:
hPipe = CreateNamedPipeA(
EXAMP_PIPE,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUF_SIZE,
BUF_SIZE,
0,
&sa);
//检查是否创建成功
if (hPipe == INVALID_HANDLE_VALUE)
{
WriteToLog("Create named Pipe Error:" + to_string(GetLastError()));
return;
}
WriteToLog("Create named Pipe success:");
等待一个客户端进行连接时,事件变成有信号状态
if (!ConnectNamedPipe(hPipe, NULL))
{
CloseHandle(hPipe);
WriteToLog("wait connect Failed:" + to_string(GetLastError()));
return;
}
else
{
WriteToLog("connect success!");
}
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) {//服务的工作线程循环
//连接成功,进行通信,读写
char szBuffer[BUF_SIZE];
::ZeroMemory(szBuffer, BUF_SIZE);
DWORD cbRead = 0;
BOOL hRead = ReadFile(hPipe, szBuffer, BUF_SIZE, &cbRead, NULL);
if (!hRead) {
//读取失败,
int t_error = GetLastError();
WriteToLog("read failed!" + to_string(t_error));
}
else {//读取成功后,将读取内容写入日志
WriteToLog("read success!");
}
//将读入的数据遍历到map中
int num = 0;
SearchFile(szBuffer, &num, &_path);
WriteToLog("end_of_reverse");
}
可以看出,客户端在退出后再重新连接是是一个动态的创建新的实例的过程,而服务端的管道是一个静态的实例,因此客户端只能通信一次,在之后进行通信的话就会报错121:信号灯超时时间已到 ;
解决的方法:我的代码中当客户端异常退出时会出现两种错误,一部分是会出现再连接时候报错error:535,error:536(目前为止遇到了这两种);另一种错误是读数据时报错109:管道结束,因此在这两部分异常终止之后重新创建新的管道实例即可,如下代码:
只用更改服务端:
//检查是否创建成功
if (hPipe == INVALID_HANDLE_VALUE)
{
WriteToLog("Create named Pipe Error:" + to_string(GetLastError()));
return;
}
WriteToLog("Create named Pipe success:");
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) {//服务的工作线程循环
//等待一个客户端进行连接时,事件变成有信号状态
if (!ConnectNamedPipe(hPipe, NULL))
{
CloseHandle(hPipe);//关闭管道
int the_error = GetLastError();
WriteToLog("wait connect Failed:" + to_string(the_error));
hPipe = CreateNamedPipeA(
EXAMP_PIPE,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUF_SIZE,
BUF_SIZE,
0,
&sa);
//检查是否创建成功
if (hPipe == INVALID_HANDLE_VALUE)
{
WriteToLog("Create named Pipe Error:" + to_string(GetLastError()));
return;
}
WriteToLog("Create named Pipe success:");
continue;
}
else
{
WriteToLog("connect success!");
}
//连接成功,进行通信,读写
char szBuffer[BUF_SIZE];
::ZeroMemory(szBuffer, BUF_SIZE);
DWORD cbRead = 0;
BOOL hRead = ReadFile(hPipe, szBuffer, BUF_SIZE, &cbRead, NULL);
if (!hRead) {
//读取失败,
int t_error = GetLastError();
WriteToLog("read failed!" + to_string(t_error));
if (t_error == 109) {
CloseHandle(hPipe);//关闭管道
hPipe = CreateNamedPipeA(
EXAMP_PIPE,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUF_SIZE,
BUF_SIZE,
0,
&sa);
//检查是否创建成功
if (hPipe == INVALID_HANDLE_VALUE)
{
WriteToLog("Create named Pipe Error:" + to_string(GetLastError()));
return;
}
WriteToLog("Create named Pipe success:");
continue;
}
}
else {//读取成功后,将读取内容写入日志
WriteToLog("read success!");
}
//将读入的数据遍历到map中
int num = 0;
SearchFile(szBuffer, &num, &_path);
WriteToLog("end_of_reverse");
}
这个问题的解决参考另一篇博客,在这里我贴上链接:信号灯超时