命名管道与邮件槽机制的比较
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
二,邮件槽与命名管道对比试验
1实验内容
编写程序,要求在客户端的命令行输入字符串并回车客户端把字符串发送到服务器,服务器再把收到的字符串传回客户端,通过命名管道及邮件槽方式完成,分析两种方式的利弊。
2试验目的
深入理解共享存储与消息传递的进程通信。
3试验原理
命名管道
命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是:命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。
邮件槽
邮件槽(Mailslots)提供进程间单向通信能力,任何进程都能建立邮件槽成为邮件槽服务器。其它进程,称为邮件槽客户,可以通过邮件槽的名字给邮件槽服务器进程发送消息。进来的消息一直放在邮件槽中,直到服务器进程读取它为止。一个进程既可以是邮件槽服务器也可以是邮件槽客户,因此可建立多个邮件槽实现进程间的双向通信。
通过邮件槽可以给本地计算机上的邮件槽、其它计算机上的邮件槽或指定网络区域中所有计算机上有同样名字的邮件槽发送消息。广播通信的消息长度不能超过400字节,非广播消息的长度则受邮件槽服务器指定的最大消息长度的限制。邮件槽与命名管道相似,不过它传输数据是通过不可靠的数据报(如TCP/IP 协议中的UDP包)完成的,一旦网络发生错误则无法保证消息正确地接收,而命名管道传输数据则是建立在可靠连接基础上的。不过邮件槽有简化的编程接口和给指定网络区域内的所有计算机广播消息的能力,所以邮件槽不失为应用程序发送和接收消息的另一种选择。
传输安全性:
由于邮槽是围绕一个广播通信体系设计出来的,所以当然不能指望能通过它实现数据的"可靠"传输;
优缺点:
邮槽最大的一个缺点便是只允许从客户机到服务器,建立一种不可靠的单向数据通信。
而另一方面,邮槽最大的一个优点在于,它们使客户机应用能够非常容易地将广播消息发给一个或多个服务器应用。
4程序源代码
命名管道服务器代码:
{
string m_sMessage;
char buffer[1024];
DWORD ReadNum;
HANDLE m_hPipe = CreateNamedPipe("\\\\.\\Pipe\\Test",PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE|PIPE_READ MODE_BYTE,1,0,0,1000,NULL);
cout<<"~命名管道服务器界面~\n\n\n";
if(m_hPipe==INVALID_HANDLE_VALUE)
{
m_sMessage="创建命名管道失败!";
cout< return 0; } else { m_sMessage="成功创建命名管道!"; cout< } if(ConnectNamedPipe(m_hPipe,NULL)==FALSE) { CloseHandle(m_hPipe); m_sMessage="与客户机建立连接失败!"; return 0; } else { m_sMessage="与客户机连接成功!"; cout< while(true) { if(ReadFile(m_hPipe,buffer,sizeof(buffer),&ReadNum,NULL)==FALSE) { CloseHandle(m_hPipe); cout<<"读取失败!"< return 0; } else { cout<<"来自客户端的数据为:"; buffer[ReadNum]='\0'; cout< cout<<"向客户端回发数据"< if(WriteFile(m_hPipe,buffer,strlen(buffer),&ReadNum,NULL)==FALSE) { cout<<"数据发送失败!"< } else { cout<<"数据发送成功"< } } } } if(DisconnectNamedPipe(m_hPipe)==FALSE) { m_sMessage="终止连接失败!"; cout< } else { CloseHandle(m_hPipe); m_sMessage="成功终止连接!"; cout< } return 0; } 命名管道客户端代码: { char message[1000] ; DWORD WriteNum; cout<<"~命名管道客户端界面~\n\n\n"; if(WaitNamedPipe("\\\\.\\Pipe\\Test",NMPWAIT_WAIT_FOREVER)==FALSE) { cout<<"等待连接失败!"< return 0; } HANDLE hPipe =CreateFile("\\\\.\\Pipe\\Test",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING ,FILE_ATTRIBUTE_NORMAL,NULL); if(hPipe==INVALID_HANDLE_VALUE) { cout<<"管道打开失败!"< return 0; } else { cout<<"成功打开管道"< }