此工作空间也是双工程
不同的是,服务端与客户端分别独立打开
服务端点击<创建管道>后,在被客户端连接之前,将处于一个未响应状态
以下是服务端===================================================================
private:
HANDLE hPipe;
public:
afx_msg void OnDestroy();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
在initDlg中
this->hPipe=NULL;
在ON_DESTROY中
if(this->hPipe)
{
::CloseHandle(this->hPipe);
}
void CMy0701ADlg::OnBnClickedButton1() //创建命名管道
{
// TODO: Add your control notification handler code here
this->hPipe=::CreateNamedPipeA(
<span style="font-family: Arial, Helvetica, sans-serif;">"\\\\.\\pipe\\MyPipe"</span><span style="font-family: Arial, Helvetica, sans-serif;">, //如果想指定两个反斜杠,代码中就要有四个反斜杠</span>
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, //双向模式,允许重叠模式
0, //管道类型,读取和等待方式,0表示默认字节类型和字节读方式
1, //管道实例的最大数目 (只有一个客户端)
1024, <span style="white-space:pre"> </span>//输出缓冲区大小
1024, //输入缓冲区大小
0, //指定输出值
NULL); //安全属性
if(INVALID_HANDLE_VALUE==this->hPipe)
{
::AfxMessageBox("创建命名管道失败!");
hPipe=NULL;
return;
}
//创建匿名的人工重置事件对象
HANDLE hEvent;
hEvent=::CreateEventA(NULL,TRUE,FALSE,NULL);
if(!hEvent)
{
::AfxMessageBox("创建事件对象失败!");
::CloseHandle(hPipe);
hPipe=NULL;
return;
}
OVERLAPPED ovlap; //OVERLAPPED结构
ZeroMemory(&ovlap,sizeof(OVERLAPPED));
ovlap.hEvent=hEvent;
//等待客户端请求的到来
if(!::ConnectNamedPipe(hPipe,&ovlap))
{
if(ERROR_IO_PENDING != ::GetLastError()) //ERROR_IO_PENDING 表明这个操作是一个未决的操作,不代表失败
{
::AfxMessageBox("等待客户端连接失败!");
::CloseHandle(this->hPipe);
::CloseHandle(hEvent);
hPipe=NULL;
return;
}
}
if(WAIT_FAILED==::WaitForSingleObject(hEvent,INFINITE)) //等待事件对象变为有对象
//ovlap.hEvent和hEvent标识的是同一个对象
//INFINITE 线程永远等待
{
::AfxMessageBox("等待对象失败!");
::CloseHandle(this->hPipe);
::CloseHandle(hEvent);
hPipe=NULL;
return;
}
::CloseHandle(hEvent);
}
void CMy0701ADlg::OnBnClickedButton2() //读
{
// TODO: Add your control notification handler code here
char buf[100];
DWORD dwRead;
if(!::ReadFile(this->hPipe,buf,100,&dwRead,NULL))
{
::AfxMessageBox("读取数据失败!");
return;
}
//::AfxMessageBox(buf);
this->GetDlgItem(IDC_EDIT2)->SetWindowTextA(buf);
}
void CMy0701ADlg::OnBnClickedButton3() //写
{
// TODO: Add your control notification handler code here
char buf[]="此消息来自于服务器";
DWORD dwWrite;
if(!::WriteFile(this->hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
::AfxMessageBox("写入数据失败!");
return;
}
}
以下是客户端===================================================================
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
private:
HANDLE hPipe;
public:
afx_msg void OnDestroy();
InitDlg中
this->hPipe=NULL;
ON_DESTROY
void CclientDlg::OnDestroy()
{
CDialogEx::OnDestroy();
// TODO: Add your message handler code here
if(this->hPipe)
{
::CloseHandle(this->hPipe);
}
}
void CclientDlg::OnBnClickedButton1() //连接管道
{
// TODO: Add your control notification handler code here
//要先判断一下是否有可以利用的命名管道
if(!::WaitNamedPipeA(<span style="font-family: Arial, Helvetica, sans-serif;">"</span><span style="font-family: Arial, Helvetica, sans-serif;">\\\\.\\pipe\\MyPipe"</span><span style="font-family: Arial, Helvetica, sans-serif;">,NMPWAIT_WAIT_FOREVER))</span>
{
::AfxMessageBox("当前没有可利用的命名管道实例!");
return;
}
//打开管道,与服务器通信
this->hPipe=::CreateFileA(
<span style="white-space:pre"> </span>"<span style="font-family: Arial, Helvetica, sans-serif;">\\\\.\\pipe\\MyPipe"</span><span style="font-family: Arial, Helvetica, sans-serif;">,</span><span style="white-space:pre">
</span> GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == this->hPipe)
{
::AfxMessageBox("打开命名管道失败!");
this->hPipe=NULL;
return;
}
}
void CclientDlg::OnBnClickedButton2() //读取数据
{
// TODO: Add your control notification handler code here
char buf[100];
DWORD dwRead;
if(!::ReadFile(this->hPipe,buf,100,&dwRead,NULL))
{
::AfxMessageBox("读取数据失败!");
return;
}
//::AfxMessageBox(buf);
this->GetDlgItem(IDC_EDIT2)->SetWindowTextA(buf);
}
void CclientDlg::OnBnClickedButton3() //写入数据
{
// TODO: Add your control notification handler code here
char buf[]="此文字来自于客户端";
DWORD dwWrite;
if(!::WriteFile(this->hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
::AfxMessageBox("写入数据失败");
return;
}
}