命名管道写入时总是出错

sj720618 2013-06-24 09:27:00
我想用命名管道实现两个进程间的通信, 但是两个进程都是又读又写, 而且打开的顺序不能确定, 所以不能分出server和client来. 我打算通过CreateFile的返回值来判定管道是否已经存在, 代码看起来一切正常, 但是到了ReadFile或者WriteFile的时候发现操作出错, GetLastError()返回6, 无效句柄. 求大神指点~

InterProcessChannel::InterProcessChannel( DWORD pid ) {
DWORD max_pid = GetCurrentProcessId(), min_pid = pid;
MaxMin(max_pid, min_pid);
std::wstring pipe_name = PIPE_PREFIX +
I2WString(max_pid) + L"_" + I2WString(min_pid);
DWORD err;
connect_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);

// 先尝试打开已有管道
pipe_ = CreateFile(pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (pipe_ == INVALID_HANDLE_VALUE) {
err = GetLastError();
if (err != ERROR_FILE_NOT_FOUND)
throw std::runtime_error("CreateFile failed. GetLastError == " +
I2String(err));

// ERROR_NOT_FOUND 说明这个管道还没有创建, 所以需要创建一个
pipe_ = CreateNamedPipe(pipe_name.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
1, MAX_BUFF_SIZE, MAX_BUFF_SIZE, 0, NULL);
if (pipe_ == INVALID_HANDLE_VALUE)
throw std::runtime_error("CreateNamedPipe failed. GetLastError == " +
I2String(GetLastError()));

// 等待对方连接
Request *req = RequestsPool::Get();
req->hEvent = connect_event_;
BOOL conn_f = ConnectNamedPipe(pipe_, req);
if (!conn_f) {
err = GetLastError();
if (err != ERROR_IO_PENDING && err != ERROR_PIPE_CONNECTED)
throw std::runtime_error("ConnectNamedPipe failed. GetLastError == " +
I2String(err));
}
} else {
// 管道已存在, 修改为消息模式
DWORD mode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(pipe_, &mode, NULL, NULL))
throw std::runtime_error("SetNamedPipeHandleState failed. GetLastError == " +
I2String(GetLastError()));
SetEvent(connect_event_);
}

// 为管道创建完成端口
if ((completion_port_ = CreateIoCompletionPort(pipe_, NULL, 0, 0)) == NULL)
throw std::runtime_error("CreateIoCompletionPort failed. GetLastError == " +
I2String(GetLastError()));

// 等待连接建立
if (WaitForSingleObject(connect_event_, INFINITE) != WAIT_OBJECT_0)
throw std::runtime_error("WaitForSingleObject failed. GetLastError == " +
I2String(GetLastError()));

// 第一次读取
Request *req = RequestsPool::Get();
if (ReadFile(pipe_, req->read_buff, MAX_BUFF_SIZE, NULL, req) == FALSE)
if ((err = GetLastError()) != ERROR_IO_PENDING)
throw std::runtime_error("ReadFile failed. GetLastError == " +
I2String(GetLastError()));

// 没有异常, 创建线程开始处理IO结果
CreateThread(NULL, 0, DispatchThread_, this, NULL, NULL);
return ;
}
...全文
182 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
shengguangde 2013-12-31
  • 打赏
  • 举报
回复
引用 3 楼 sj720618 的回复:
找到问题所在了...这个Request类是从OVERLAPPED派生出来的, 应该改成包含一个OVERLAPPED的数据成员
不懂,麻烦再解释一下,Request跟pipe_句柄有什么关系?
sj720618 2013-06-26
  • 打赏
  • 举报
回复
找到问题所在了...这个Request类是从OVERLAPPED派生出来的, 应该改成包含一个OVERLAPPED的数据成员
sj720618 2013-06-24
  • 打赏
  • 举报
回复
引用 1 楼 sha_jinhao 的回复:
打开的顺序不能确定, ----- 应该先启动server
可是我区分不开哪个是server啊, 两个进程都是互有读写的, 只能是先启动的进程创建管道, 后启动的进程打开已有管道. 每个API我都判断了返回值, 一路都是按照预期执行到ReadFile那里的, 但是每次都报句柄无效
jimette 2013-06-24
  • 打赏
  • 举报
回复
打开的顺序不能确定, ----- 应该先启动server

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧