荒废的光阴,最后得自己一点点捡起来。个人笔记,有误请直接评论提出,共同学习。
进程间通信方式:邮槽、管道、剪贴板、消息、网络、FileMapping。
一、邮槽
邮槽通信进程分服务端和客户端,由服务端创建并指定邮槽名,客户端根据邮槽名打开使用。单向通信,客户端写+服务端读,消息先进先出。可跨主机,单条消息不能超过424字节。
1,关键API
1)服务端创建邮槽CreateMailslot
2)服务端获取邮槽信息GetMailslotInfo
3)服务端读取消息ReadFile
4)客户端打开邮槽CreateFile
5)客户端向邮槽中写入信息WriteFile
2,服务端实例
//邮槽通信服务端
#include<stdio.h>
#include<Windows.h>
HANDLE hSlot;//邮槽句柄
LPTSTR lpszSlotName = (LPTSTR)TEXT("\\\\.\\mailslot\\sample_mailsolt");//邮槽名
void main()
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
char lpszBuffer[1024];
char achID[128];
DWORD cAllMessages;
HANDLE hEvemt;
OVERLAPPED ov;
cbMessage = cMessage = cbRead = 0;
//创建邮槽
hSlot = CreateMailslot(
lpszSlotName, //管道名
0, //不限制消息大小
MAILSLOT_WAIT_FOREVER, //无超时
(LPSECURITY_ATTRIBUTES)NULL
);
//创建邮槽失败
if (hSlot == INVALID_HANDLE_VALUE)
{
printf("CreateMailslot failed with %d.\n", GetLastError());
return;
}
else//创建邮槽成功
{
printf("Mailslot created successeffully.\n ");
}
while (true)
{
//获取邮槽信息
fResult = GetMailslotInfo(
hSlot, //邮槽句柄
(LPDWORD)NULL, //无最大消息限制
&cbMessage, //下一条消息的大小
&cMessage, //消息数量
(LPDWORD)NULL //无限时
);
//取信息失败
if (!fResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
return;
}
//无消息
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
Sleep(2000);
continue;
}
//取消息处理
cAllMessages = cMessage;;
while (cMessage != 0)//逐条消息处理
{
//提示信息
sprintf_s(
achID,
"\n Message #%d of %d\n",
cAllMessages - cMessage + 1,
cAllMessages
);
//读取消息
fResult = ReadFile(
hSlot, //邮槽句柄
lpszBuffer, //缓存
cbMessage, //消息长度
&cbRead, //实际读取长度
NULL
);
//取消息失败
if (!fResult)
{
printf("ReadFile failed with %d.\n", GetLastError());
return;
}
//处理消息,显示
SYSTEMTIME st;
GetLocalTime(&st);
printf("%02d:%02d:%02d.%03d Contents of the mailslot :%s[%s]\n", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, achID, lpszBuffer);
//计算剩余消息数
fResult = GetMailslotInfo(
hSlot, //邮槽句柄
(LPDWORD)NULL, //无最大消息限制
&cbMessage, //下一条消息的大小
&cMessage, //消息数量
(LPDWORD)NULL //无限时
);
//取信息失败
if (!fResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
return;
}
}
}
}
3,客户端实例
//邮槽通信客户端
#include<stdio.h>
#include<Windows.h>
HANDLE hSlot;//邮槽句柄
LPTSTR lpszSlotName = (LPTSTR)TEXT("\\\\.\\mailslot\\sample_mailsolt");//邮槽名
char *lpszMessage = (char *)"Message for mailslot in primary domain.";//信息
void main()
{
BOOL fResult;
HANDLE hFile;
DWORD cbWritten;
DWORD cbMessage;
//打开邮槽
hFile = CreateFile(
lpszSlotName, //邮槽名
GENERIC_WRITE, //可写
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING, //打开已存在的邮槽,服务端创建
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL
);
//打开邮槽失败
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed with %d.\n", GetLastError());
return;
}
//向邮槽中写入信息
fResult = WriteFile(
hFile, //邮槽写文件句柄
lpszMessage, //待写入信息
(DWORD)(strlen(lpszMessage) + 1) * sizeof(TCHAR),
&cbWritten, //实际写入长度
(LPOVERLAPPED)NULL
);
//写信息失败
if (!fResult)
{
printf("WriteFile failed with %d.\n", GetLastError());
return;
}
printf("Slot writen to successfully.\n");
//实时输入写入
char cInMessage[512] = {0};
printf("Input message:");
while (scanf_s("%s", cInMessage, 512))
{
//向邮槽中写入信息
fResult = WriteFile(
hFile, //邮槽写文件句柄
cInMessage, //待写入信息
(DWORD)(strlen(cInMessage) + 1) * sizeof(TCHAR),
&cbWritten, //实际写入长度
(LPOVERLAPPED)NULL
);
//写信息失败
if (!fResult)
{
printf("WriteFile failed with %d.\n", GetLastError());
return;
}
SYSTEMTIME st;
GetLocalTime(&st);
printf("%02d:%02d:%02d.%03d Slot writen to successfully.\n", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
printf("Input message:");
}
CloseHandle(hFile);//关闭写邮槽句柄
}
4,运行效果
二、管道
管道通讯本机进程间共享数据,是一段共享内存。
匿名管道:只能在父子进程间通信,数据传输单向。
命名管道:可以在任意进程通信,双向读写,同一时间只能一 端读、一端写。
1,关键API
2,服务端实例
3,客户端实例
4,运行效果