您的位置:首页 > 编程语言 > C语言/C++

MFC(进程间的通信,孙鑫C++第十七讲笔记整理)

2013-10-22 11:31 681 查看
有四种方法

1.剪贴板

a.创建个ClipBoard的对话框应用程序,加两EditBox和两个Button发送接收。

b.具体代码:

发送端代码:

if(OpenClipboard())

{

CString str;

HANDLE hClip;

char *pBuf;

EmptyClipboard();

GetDlgItemText(IDC_EDIT_SEND,str);

hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);

pBuf=(char*)GlobalLock(hClip);将句柄转换为指针!

strcpy(pBuf,str);

GlobalUnlock(hClip);

SetClipboardData(CF_TEXT,hClip);

CloseClipboard();

}

接收端代码:

if(OpenClipboard())

{

if(IsClipboardFormatAvailable(CF_TEXT))

{

HANDLE hClip;

char *pBuf;

hClip=GetClipboardData(CF_TEXT);

pBuf=(char*)GlobalLock(hClip);

GlobalUnlock(hClip);

SetDlgItemText(IDC_EDIT_RECV,pBuf);

CloseClipboard();

}

}

2.匿名管道:只能在父子进程之间进行通信

a.先建一个Parent的单文档应用程序,增加“创建管道”“读取数据”“写入数据”三个菜单

b.增加成员变量HANDLE类型的hRead,hWrite,初始化变量,并在析构函数中释放句柄

c.响应菜单代码:

void CParentView::OnPipeCreate()菜单“创建管道”代码

{

// TOD Add your command handler code here

SECURITY_ATTRIBUTES sa;

sa.bInheritHandle=TRUE;

sa.lpSecurityDescriptor=NULL;

sa.nLength=sizeof(SECURITY_ATTRIBUTES);

if(!CreatePipe(&hRead,&hWrite,&sa,0))

{

MessageBox("创建匿名管道失败!");

return;

}

STARTUPINFO sui;

PROCESS_INFORMATION pi;

ZeroMemory(&sui,sizeof(STARTUPINFO));将数据清0!

sui.cb=sizeof(STARTUPINFO);

sui.dwFlags=STARTF_USESTDHANDLES;

sui.hStdInput=hRead;

sui.hStdOutput=hWrite;

sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);

if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,

TRUE,0,NULL,NULL,&sui,&pi))创建子进程

{

CloseHandle(hRead);

CloseHandle(hWrite);关闭句柄,将内核对象的使用计数减少1,这样当操作系统发现内核对象的使用计数为0时,将清除内核对象。

hRead=NULL;

hWrite=NULL;

MessageBox("创建子进程失败!");

return;

}

else

{

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

}

}void CParentView::OnPipeRead()菜单“读取数据”代码

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hRead,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CParentView::OnPipeWrite()菜单“写入数据”代码

{

// TOD Add your command handler code here

char buf[]="http://www.sunxin.org";

DWORD dwWrite;

if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}

d.再建一个Child的单文档,在View中增加两个成员hRead和hWrite.在OnInitialUpdate()中得到句柄的值。

void CChildView::OnInitialUpdate()

{

CView::OnInitialUpdate();

// TOD Add your specialized code here and/or call the base class

hRead=GetStdHandle(STD_INPUT_HANDLE);注意这句代码!

hWrite=GetStdHandle(STD_OUTPUT_HANDLE);

} e.加菜单“读取数据”“写入数据”其代码如下:

void CChildView::OnPipeRead()

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hRead,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CChildView::OnPipeWrite()

{

// TOD Add your command handler code here

char buf[]="匿名管道测试程序";

DWORD dwWrite;

if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}

3.命名管道:还可以跨网络通信,服务器只能在win2000和NT下运行!而客户端可以在95下运行。关键函数CreateNamedPipe

a.先建一个NamedPipeSRV单文档应用程序,加菜单“创建管道”“读取数据”“写入数据”

b.在View中增加Handle变量hPipe,注意在析构函数中释放它!

c.响应菜单,创建命名管道

void CNamedPipeSrvView::OnPipeCreate()

{

// TOD Add your command handler code here

hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe",

PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,

0,1,1024,1024,0,NULL);

if(INVALID_HANDLE_VALUE==hPipe)

{

MessageBox("创建命名管道失败!");

hPipe=NULL;

return;

}

HANDLE hEvent;

hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if(!hEvent)

{

MessageBox("创建事件对象失败!");

CloseHandle(hPipe);

hPipe=NULL;

return;

}

OVERLAPPED ovlap;

ZeroMemory(&ovlap,sizeof(OVERLAPPED));

ovlap.hEvent=hEvent;

if(!ConnectNamedPipe(hPipe,&ovlap))

{

if(ERROR_IO_PENDING!=GetLastError())

{

MessageBox("等待客户端连接失败!");

CloseHandle(hPipe);

CloseHandle(hEvent);

hPipe=NULL;

return;

}

}

if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))

{

MessageBox("等待对象失败!");

CloseHandle(hPipe);

CloseHandle(hEvent);

hPipe=NULL;

return;

}

CloseHandle(hEvent);

}void CNamedPipeSrvView::OnPipeRead()

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hPipe,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CNamedPipeSrvView::OnPipeWrite()

{

// TOD Add your command handler code here

char buf[]="http://www.sunxin.org";

DWORD dwWrite;

if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

} d.再建一个NamedPipeCLT单文档工程,加菜单“连接管道”“读取数据”“写入数据”,当然别忘记成员变量hPipe的定义和初始化

e.响应菜单代码

void CNamedPipeCltView::OnPipeConnect()连接管道

{

// TOD Add your command handler code here

if(!WaitNamedPipe("\\\\.\\pipe\\MyPipe",NMPWAIT_WAIT_FOREVER))

{

MessageBox("当前没有可利用的命名管道实例!");

return;

}

hPipe=CreateFile("\\\\.\\pipe\\MyPipe",GENERIC_READ | GENERIC_WRITE,

0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hPipe)

{

MessageBox("打开命名管道失败!");

hPipe=NULL;

return;

}

}void CNamedPipeCltView::OnPipeRead()读取数据

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hPipe,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CNamedPipeCltView::OnPipeWrite()写入数据

{

// TOD Add your command handler code here

char buf[]="命名管道测试程序";

DWORD dwWrite;

if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}

4.邮槽,使用时应将消息长度限制在424字节以下,关键函数CreateMailSlot()

a.先建一个MailSlotSRV工程,加菜单“接收数据”

b.消息响应代码:

void CMailslotSrvView::OnMailslotRecv()菜单“接收数据”的代码

{

// TOD Add your command handler code here

HANDLE hMailslot;

hMailslot=CreateMailslot("\\\\.\\mailslot\\MyMailslot",0,

MAILSLOT_WAIT_FOREVER,NULL);

if(INVALID_HANDLE_VALUE==hMailslot)

{

MessageBox("创建油槽失败!");

return;

}

char buf[100];

DWORD dwRead;

if(!ReadFile(hMailslot,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

CloseHandle(hMailslot);

return;

}

MessageBox(buf);

CloseHandle(hMailslot);

}

c.加工程MailSlotCLT,加菜单“发送数据”

d.加消息响应,添加代码,客户端也比较简单。

void CMailslotCltView::OnMailslotSend()菜单“发送数据”的代码

{

// TOD Add your command handler code here

HANDLE hMailslot;

hMailslot=CreateFile("\\\\.\\mailslot\\MyMailslot",GENERIC_WRITE,

FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hMailslot)

{

MessageBox("打开油槽失败!");

return;

}

char buf[]="http://www.sunxin.org";

DWORD dwWrite;

if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

CloseHandle(hMailslot);

return;

}

CloseHandle(hMailslot);

}

5.以上4种方法各有优缺点:剪贴板比较简单。邮槽是基于广播的,可以一对多发送。但只能一个发送,一个接收,要想同时发送接收,须写两次代码。

命名管道和邮槽可以进行网络通信。

剪切板

[cpp]
view plaincopyprint?

void CJieQieBanDlg::OnSend()
{
// TODO: Add your control notification handler code here

if(OpenClipboard())//首先要打开剪切板
{
CString str;
HANDLE hChip;
char *pBuf;

EmptyClipboard();//清空剪切板
GetDlgItemText(ID_FASONG,str);//获取发送数据的内容
hChip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//分配空间,返回一个句柄

pBuf=(char*)GlobalLock(hChip);//上锁,返回一个字符指针
strcpy(pBuf,str);//复制内容
GlobalUnlock(hChip);//解锁

SetClipboardData(CF_TEXT,hChip);//设置剪切板的内容

CloseClipboard();
}

}

void CJieQieBanDlg::OnSend() {	// TODO: Add your control notification handler code here	if(OpenClipboard())//首先要打开剪切板	{		CString str;		HANDLE hChip;		char *pBuf;		EmptyClipboard();//清空剪切板		GetDlgItemText(ID_FASONG,str);//获取发送数据的内容		hChip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//分配空间,返回一个句柄		pBuf=(char*)GlobalLock(hChip);//上锁,返回一个字符指针		strcpy(pBuf,str);//复制内容		GlobalUnlock(hChip);//解锁		SetClipboardData(CF_TEXT,hChip);//设置剪切板的内容		CloseClipboard();	}	}


[cpp]
view plaincopyprint?

void CJieQieBanDlg::OnRecv()
{
// TODO: Add your control notification handler code here

if(OpenClipboard())//打开剪切板
{
if(IsClipboardFormatAvailable(CF_TEXT))//判断剪切板的内容格式是否是我们需要的
{
HANDLE hChip;
char *pBuf;
hChip=GetClipboardData(CF_TEXT);//返回一个句柄
pBuf=(char*)GlobalLock(hChip);//获取内容
GlobalUnlock(hChip);
SetDlgItemText(ID_JIESHOU,pBuf);//设置内容
CloseHandle(hChip);

}
}

}

void CJieQieBanDlg::OnRecv() {	// TODO: Add your control notification handler code here		if(OpenClipboard())//打开剪切板	{		if(IsClipboardFormatAvailable(CF_TEXT))//判断剪切板的内容格式是否是我们需要的		{			HANDLE hChip;			char *pBuf;			hChip=GetClipboardData(CF_TEXT);//返回一个句柄			pBuf=(char*)GlobalLock(hChip);//获取内容			GlobalUnlock(hChip);			SetDlgItemText(ID_JIESHOU,pBuf);//设置内容			CloseHandle(hChip);		}	}}




匿名管道:

1父进程:

a添加两个CXXView成员变量HANDLE hRead,HANDLE hWrite

b构造函数赋值hRead=NULL,hWrite=NULL,析构函数if(!hRead) CloseHandle(hRead)...

c

[cpp]
view plaincopyprint?

void CParentView::OnPipeCreate()
{
// TODO: Add your command handler code here

SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);

if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
MessageBox("创建管道失败");
return ;
}

PROCESS_INFORMATION pi;

STARTUPINFO sui;
ZeroMemory(&sui,sizeof(STARTUPINFO));//这一句很重要,将数据清零
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);

if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi))
{
CloseHandle(hWrite);
CloseHandle(hRead);
hRead=NULL;
hWrite=NULL;
MessageBox("子进程创建失败");
return ;
}
else
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

}

void CParentView::OnPipeCreate() {	// TODO: Add your command handler code here	SECURITY_ATTRIBUTES  sa;	sa.bInheritHandle=TRUE;	sa.lpSecurityDescriptor=NULL;	sa.nLength=sizeof(SECURITY_ATTRIBUTES);	if(!CreatePipe(&hRead,&hWrite,&sa,0))	{		MessageBox("创建管道失败");		return ;	}	PROCESS_INFORMATION  pi;		STARTUPINFO sui;	ZeroMemory(&sui,sizeof(STARTUPINFO));//这一句很重要,将数据清零	sui.cb=sizeof(STARTUPINFO);	sui.dwFlags=STARTF_USESTDHANDLES;	sui.hStdInput=hRead;	sui.hStdOutput=hWrite;	sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);	if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi))	{		CloseHandle(hWrite);		CloseHandle(hRead);		hRead=NULL;		hWrite=NULL;		MessageBox("子进程创建失败");		return ;	}	else	{		CloseHandle(pi.hProcess);		CloseHandle(pi.hThread);	}	}


d

[cpp]
view plaincopyprint?

void CParentView::OnXieru()
{
// TODO: Add your command handler code here

char temp[]="hello,i am writing...";

unsigned long len;
if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL))
{
MessageBox("写入失败");
return ;
}

}

void CParentView::OnXieru() {	// TODO: Add your command handler code here	char temp[]="hello,i am writing...";		unsigned long len;	if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL))	{		MessageBox("写入失败");		return ;	}	}


e

[cpp]
view plaincopyprint?

void CParentView::OnDuqu()
{
// TODO: Add your command handler code here

char temp[100];
unsigned long len;

if(!ReadFile(hRead,temp,100,&len,NULL))
{
MessageBox("读取失败");
return ;
}

MessageBox(temp);

}

void CParentView::OnDuqu() {	// TODO: Add your command handler code here	char temp[100];	unsigned long len;	if(!ReadFile(hRead,temp,100,&len,NULL))	{		MessageBox("读取失败");		return ;	}	MessageBox(temp);	}


子进程

a,CXXVIEW中添加成员变量HANDLE hRead,HANDLE hWrite,在构造函数和析构函数进行响应的操作


bCXXView中添加虚函数OnInitialUpdate

[cpp]
view plaincopyprint?

void CChildView::OnInitialUpdate()
{
CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class

hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE);

}

void CChildView::OnInitialUpdate() {	CView::OnInitialUpdate();		// TODO: Add your specialized code here and/or call the base class	hRead=GetStdHandle(STD_INPUT_HANDLE);	hWrite=GetStdHandle(STD_OUTPUT_HANDLE);	}


[cpp]
view plaincopyprint?

void CChildView::OnXieru()
{
// TODO: Add your command handler code here

char temp[]="hello,wel to my blog,i am afei";
unsigned long len;
if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL))
{
MessageBox("写入数据失败");
return ;
}

}

void CChildView::OnXieru() {	// TODO: Add your command handler code here	char temp[]="hello,wel to my blog,i am afei";	unsigned long len;	if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL))	{		MessageBox("写入数据失败");		return ;	}	}


[cpp]
view plaincopyprint?

void CChildView::OnDuqu()
{
// TODO: Add your command handler code here

char temp[100];
unsigned long len;

if(!ReadFile(hRead,temp,100,&len,NULL))
{
MessageBox("读取数据失败");
return ;
}
MessageBox(temp);

}

void CChildView::OnDuqu() {	// TODO: Add your command handler code here	char temp[100];	unsigned long len;	if(!ReadFile(hRead,temp,100,&len,NULL))	{		MessageBox("读取数据失败");		return ;	}	MessageBox(temp);	}


先启动父进程,然后通过父进程建立子进程,然后就能实现父子进程之间的通信了。



命名管道:(可跨网络)

1服务器端:

a,CXXView中添加成员变量HANDLE hPipe

b,

[cpp]
view plaincopyprint?

void CNamePipeSerView::OnPipeCreate()
{
// TODO: Add your command handler code here

hPipe=CreateNamedPipe("\\\\.\\pipe\\mypipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
0,1,1024,1024,0,NULL);//要转义

if(INVALID_HANDLE_VALUE==hPipe)
{
MessageBox("命名管道创建失败");
hPipe=NULL;
return ;
}

HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!hEvent)
{
MessageBox("对象事件创建失败");
return ;
}

OVERLAPPED oa;
ZeroMemory(&oa,sizeof(OVERLAPPED));
oa.hEvent=hEvent;
if(!ConnectNamedPipe(hPipe,&oa))
{
if(ERROR_IO_PENDING!=GetLastError())
{

MessageBox("命名管道连接失败");
CloseHandle(hEvent);
CloseHandle(hPipe);
hEvent=NULL;
hPipe=NULL;

return ;
}
}

if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))
{
MessageBox("对象等待失败");
CloseHandle(hEvent);
CloseHandle(hPipe);
hEvent=NULL;
hPipe=NULL;
return ;
}

}

void CNamePipeSerView::OnPipeCreate() {	// TODO: Add your command handler code here		hPipe=CreateNamedPipe("\\\\.\\pipe\\mypipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,				0,1,1024,1024,0,NULL);//要转义	if(INVALID_HANDLE_VALUE==hPipe)	{		MessageBox("命名管道创建失败");		hPipe=NULL;		return ;	}	HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);	if(!hEvent)	{		MessageBox("对象事件创建失败");		return ;	}	OVERLAPPED oa;	ZeroMemory(&oa,sizeof(OVERLAPPED));	oa.hEvent=hEvent;	if(!ConnectNamedPipe(hPipe,&oa))	{		if(ERROR_IO_PENDING!=GetLastError())		{				MessageBox("命名管道连接失败");		CloseHandle(hEvent);		CloseHandle(hPipe);		hEvent=NULL;		hPipe=NULL;		return ;		}	}	if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))	{		MessageBox("对象等待失败");		CloseHandle(hEvent);		CloseHandle(hPipe);		hEvent=NULL;		hPipe=NULL;		return ;	}}


[cpp]
view plaincopyprint?

void CNamePipeSerView::OnXieru()
{
// TODO: Add your command handler code here

char temp[]="hello,i am afei";

unsigned long len;
if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL))
{
MessageBox("写入文件失败");
return ;
}

}

void CNamePipeSerView::OnXieru() {	// TODO: Add your command handler code here	char temp[]="hello,i am afei";		unsigned long len;	if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL))	{		MessageBox("写入文件失败");		return ;	}	}


[cpp]
view plaincopyprint?

void CNamePipeSerView::OnDuqu()
{
// TODO: Add your command handler code here

char temp[100];

unsigned long len;
if(!ReadFile(hPipe,temp,100,&len,NULL))
{
MessageBox("读取文件失败");
return ;
}

MessageBox(temp);

}

void CNamePipeSerView::OnDuqu() {	// TODO: Add your command handler code here	char temp[100];		unsigned long len;	if(!ReadFile(hPipe,temp,100,&len,NULL))	{		MessageBox("读取文件失败");		return ;	}		MessageBox(temp);	}


客户端:

[cpp]
view plaincopyprint?

void CNamePipeCliView::OnLianjie()
{
// TODO: Add your command handler code here

if(!WaitNamedPipe("\\\\.\\pipe\\mypipe",NMPWAIT_WAIT_FOREVER))
{
MessageBox("没有可用的命名管道实例");
return ;
}

hPipe=CreateFile("\\\\.\\pipe\\mypipe",GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hPipe)
{
MessageBox("打开管道失败");
hPipe=NULL;
return ;
}

}

void CNamePipeCliView::OnLianjie() {	// TODO: Add your command handler code here	if(!WaitNamedPipe("\\\\.\\pipe\\mypipe",NMPWAIT_WAIT_FOREVER))	{		MessageBox("没有可用的命名管道实例");		return ;	}	hPipe=CreateFile("\\\\.\\pipe\\mypipe",GENERIC_READ|GENERIC_WRITE,0,NULL,		OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);	if(INVALID_HANDLE_VALUE==hPipe)	{		MessageBox("打开管道失败");		hPipe=NULL;		return ;	}	}


[cpp]
view plaincopyprint?

void CNamePipeCliView::OnXieru()
{
// TODO: Add your command handler code here

char temp[]="i love C++,MFC...";
unsigned long len;
if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL))
{

MessageBox("写入文件失败");

return ;
}

}

void CNamePipeCliView::OnXieru() {	// TODO: Add your command handler code here		char temp[]="i love C++,MFC...";	unsigned long len;	if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL))	{		MessageBox("写入文件失败");		return ;	}	}


[cpp]
view plaincopyprint?

void CNamePipeCliView::OnDuqu()
{
// TODO: Add your command handler code here

char temp[100];

unsigned long len;
if(!ReadFile(hPipe,temp,100,&len,NULL))
{
MessageBox("读取文件失败");
return ;
}

MessageBox(temp);

}

void CNamePipeCliView::OnDuqu() {	// TODO: Add your command handler code here	char temp[100];	unsigned long len;	if(!ReadFile(hPipe,temp,100,&len,NULL))	{		MessageBox("读取文件失败");		return ;	}	MessageBox(temp);	}


这样就可以实现两个进程之间的通信了,



邮槽:(一对多)

1服务器端(接收数据)

[cpp]
view plaincopyprint?

void CYouCaoSerView::OnJieshou()
{
// TODO: Add your command handler code here

HANDLE hMail;
hMail=CreateMailslot("\\\\.\\mailslot\\mymail",0,MAILSLOT_WAIT_FOREVER,NULL);

if(INVALID_HANDLE_VALUE==hMail)
{
MessageBox("创建油槽失败");
return ;
}

char temp[200];
DWORD dwlen;
if(!ReadFile(hMail,temp,200,&dwlen,NULL))
{
CloseHandle(hMail);
MessageBox("读取失败");
return ;
}
CloseHandle(hMail);
MessageBox(temp);

}

void CYouCaoSerView::OnJieshou() {	// TODO: Add your command handler code here	HANDLE hMail;	hMail=CreateMailslot("\\\\.\\mailslot\\mymail",0,MAILSLOT_WAIT_FOREVER,NULL);	if(INVALID_HANDLE_VALUE==hMail)	{		MessageBox("创建油槽失败");		return ;	}	char temp[200];	DWORD dwlen;	if(!ReadFile(hMail,temp,200,&dwlen,NULL))	{		CloseHandle(hMail);		MessageBox("读取失败");		return ;	}	CloseHandle(hMail);	MessageBox(temp);	}


2客户端:(发送数据)

[cpp]
view plaincopyprint?

void CYouCaoCView::OnFasong()
{
// TODO: Add your command handler code here

HANDLE hMail;
hMail=CreateFile("\\\\.\\mailslot\\mymail",GENERIC_WRITE,FILE_SHARE_READ,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hMail)
{
MessageBox("打开油槽失败");
return ;
}

char temp[]="hello,welcome to my blog,i am afei";
DWORD dwlen;
if(!WriteFile(hMail,temp,strlen(temp)+1,&dwlen,NULL))
{
CloseHandle(hMail);
MessageBox("写入数据失败");
return ;
}

CloseHandle(hMail);

}

void CYouCaoCView::OnFasong() {	// TODO: Add your command handler code here	HANDLE hMail;	hMail=CreateFile("\\\\.\\mailslot\\mymail",GENERIC_WRITE,FILE_SHARE_READ,NULL,					OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);	if(INVALID_HANDLE_VALUE==hMail)	{		MessageBox("打开油槽失败");		return ;	}	char temp[]="hello,welcome to my blog,i am afei";	DWORD dwlen;	if(!WriteFile(hMail,temp,strlen(temp)+1,&dwlen,NULL))	{		CloseHandle(hMail);		MessageBox("写入数据失败");		return ;	}	CloseHandle(hMail);	}


要先打开服务器端的接收消息,这样客户端的发送消息才能打开油槽



要实现可以发送又可以接收的油槽运用程序,可以在同一个程序中,既编写客户端又编写服务器

转自:/article/2449704.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: