• window API一天一练之邮槽


    邮槽通信的进程分为服务端和客户端.服务端创建邮槽,客户端通过邮槽名打开邮槽,获得句柄后可以向邮槽写数据. 邮槽通信是单向通信,只能由客户端向服务端发送数据.下面来看看有关邮槽的几个API

    HANDLE WINAPICreateMailslot(

     _In_      LPCTSTR lpName,

      _In_      DWORDnMaxMessageSize,

      _In_      DWORDlReadTimeout,

      _In_opt_  LPSECURITY_ATTRIBUTESlpSecurityAttributes

    );

    功能:创建一个邮槽

    参数:  lpName   指定的邮槽名,格式必须为  \.mailslot[path]name

    nMaxMessageSize  可以写到邮槽中的单个消息的最大字节数,如果为0则表示可以是任意大小的消息.

    lReadTimeout    读取操作可以等待多久,0表示没有可读的消息则直接返回, MAILSLOT_WAIT_FOREVER表示一直等待可读消息.

    lpSecurityAttributes  安全属性结构体指针,   可以为NULL

    返回值: 如果成功,返回邮槽句柄,服务端通过句柄操作邮槽.如果失败则返回INVALID_HANDLE_VALUE

    BOOL WINAPI GetMailslotInfo(
      _In_       HANDLE hMailslot,
      _Out_opt_  LPDWORD lpMaxMessageSize,
      _Out_opt_  LPDWORD lpNextSize,
      _Out_opt_  LPDWORD lpMessageCount,
      _Out_opt_  LPDWORD lpReadTimeout
    );

    功能:获取有关邮槽的信息

    参数: hMailslot  邮槽句柄

    lpMaxMessageSize     单个消息的最大字节数, 也可以为NULL

    lpNextSize   下一个消息的大小,可以为NULL,为MAILSLOT_NO_MESSAGE表示没有下一个消息

    lpMessageCount  等待读取的消息数, 可以为NULL,

    lpReadTimeout   等待可读消息的时间, 也可以为NULL

    返回值:成功返回非0,失败返回0

    BOOL WINAPI SetMailslotInfo(
      _In_  HANDLE hMailslot,
      _In_  DWORD lReadTimeout
    );
     

    功能:设置等待可读消息的超时时间


    服务端通过ReadFile从邮槽中读取数据,客户端通过CreateFile打开邮槽,WriteFile向邮槽写数据。以下是我用Qt做的简单验证程序,由于不熟悉window窗台程序,所以只能用Qt了。

    客户端代码

    MailSlotClient::MailSlotClient(QWidget *parent, Qt::WFlags flags)
    	: QDialog(parent, flags)
    {
    	m_pMailSlotNameLbl = new QLabel(tr("MailSlot Name:"),this);
    	m_pMailSlotNameLEdit = new QLineEdit(this);
    	m_pMessageText = new QTextEdit(this);
    	m_pMainLayout = new QGridLayout(this);
    	m_pSendMessageBtn = new QPushButton(tr("Send Message "),this);
    	this->setLayout(m_pMainLayout);
    	m_pMainLayout->addWidget(m_pMailSlotNameLbl,0,0,1,1);
    	m_pMainLayout->addWidget(m_pMailSlotNameLEdit,0,1,1,1);
    	m_pMainLayout->addWidget(m_pSendMessageBtn,0,2,1,1);
    	m_pMainLayout->addWidget(m_pMessageText,1,0,4,4);
    	connect(m_pSendMessageBtn,SIGNAL(clicked()),this,SLOT(SendMessageSlot()));
    	//ui.setupUi(this);
    }
    
    MailSlotClient::~MailSlotClient()
    {
    
    }
    
    void MailSlotClient::SendMessageSlot()
    {
    	QString name = m_pMailSlotNameLEdit->text();
    	string szMailSlotName = (string("\\.\mailslot\") + name.toStdString()).c_str();
    	//LPSTR szMailSlotName = "\\.\mailslot\simplemailslot";
    	HANDLE hFile ;
    	hFile = CreateFile(szMailSlotName.c_str(),GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    	if (hFile == INVALID_HANDLE_VALUE)
    	{
    		QMessageBox::information(this,tr("提示"),tr("打开邮槽失败!"),QMessageBox::Ok);
    		return ;
    	}
    	DWORD dwWriteSize;
    	string message = m_pMessageText->toPlainText().toStdString();
    	WriteFile(hFile,message.c_str(),message.size(),&dwWriteSize,NULL);
    	CloseHandle(hFile);
    }
    


    服务端代码:

    MailSlotServer::MailSlotServer(QWidget *parent, Qt::WFlags flags)
    	: QDialog(parent, flags)
    {
    	m_pMailSlotNameLbl = new QLabel(tr("MailSlot Name:"),this);
    	m_pMailSlotNameLEdit = new QLineEdit(this);
    	m_pMessageText = new QTextEdit(this);
    	m_pMainLayout = new QGridLayout(this);
    	m_pCreateMailSlotBtn = new QPushButton(tr("Create MailSlot "),this);
    	this->setLayout(m_pMainLayout);
    	m_pMainLayout->addWidget(m_pMailSlotNameLbl,0,0,1,1);
    	m_pMainLayout->addWidget(m_pMailSlotNameLEdit,0,1,1,1);
    	m_pMainLayout->addWidget(m_pCreateMailSlotBtn,0,2,1,1);
    	m_pMainLayout->addWidget(m_pMessageText,1,0,4,4);
    	connect(m_pCreateMailSlotBtn,SIGNAL(clicked()),this,SLOT(CreateMailSlot()));
    }
    
    MailSlotServer::~MailSlotServer()
    {
    
    }
    
    
    
    void MailSlotServer::CreateMailSlot()
    {
    	HANDLE hMailSlot;
    	QString name = m_pMailSlotNameLEdit->text();
    	string szMailSlotName = (string("\\.\mailslot\") + name.toStdString()).c_str();
    	hMailSlot = CreateMailslot(szMailSlotName.c_str() ,0,MAILSLOT_WAIT_FOREVER,NULL);
    
    	if (hMailSlot == INVALID_HANDLE_VALUE)
    	{
    		QMessageBox::information(this,tr("提示"),tr("创建邮槽失败!"),QMessageBox::Ok);
    		return ;
    	}
    
    	DWORD dwMessageCount = 0;
    	DWORD dwMessageSize = 0;
    	DWORD dwReadSize = 0;
    	bool bFinish =false;
    	while (TRUE)
    	{
    		BOOL bResult = GetMailslotInfo(hMailSlot,NULL,&dwMessageSize,&dwMessageCount,NULL);
    		if (!bResult)
    		{
    			QMessageBox::information(this,tr("提示"),tr("获取邮槽信息失败!"),QMessageBox::Ok);
    			return ;
    		} 
    			while (dwMessageCount != 0)
    			{
    				char *lpBuffer = new char[dwMessageSize];
    				memset(lpBuffer,0,dwMessageSize);
    				ReadFile(hMailSlot,lpBuffer,dwMessageSize,&dwReadSize,NULL);
    				
    				m_pMessageText->setText(QString::fromStdString(lpBuffer));
    				GetMailslotInfo(hMailSlot,NULL,&dwMessageSize,&dwMessageCount,NULL);
    				bFinish = true;    
    			}
    		if (bFinish)   //读取完了就返回,不然一直卡住就没法显示接收到的数据了
    
    		{
    			return;
    		}
    	}
    }
    


    先启动服务端,输入邮槽名,创建邮槽,程序循环等待客户端发来数据。接收到数据后显示。再启动客户端,输入邮槽名,输入要发送的数据,点击发送,数据将显示在服务端。



  • 相关阅读:
    为什么未来是全栈project师的世界?
    剑指Offer面试题10(Java版):二进制中的1的个数
    arm-linux内存管理学习笔记(1)-内存页表的硬件原理
    高速掌握Lua 5.3 —— 字符串库 (2)
    C语言实现使用动态数组来构造栈结构
    [自学AndroidStudio系列]第二篇章:高速上手AS小技巧其一
    苹果新的编程语言 Swift 语言进阶(十三)--类型检查与类型嵌套
    JAVA 安装JDK注意事项
    hdu 1398 Square Coins(母函数)
    百度有道雅虎的实习面试经历
  • 原文地址:https://www.cnblogs.com/pangblog/p/3423958.html
Copyright © 2020-2023  润新知