服务端:
头文件:
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <string>
#include <cstring>
#include <iostream>
#include <process.h>
using namespace std;
class NamePipe{
public:
NamePipe(){
}
~NamePipe(){
if (hPipe){
CloseHandle(hPipe);
}
}
void onPipeCreate();
static DWORD WINAPI onPipeRead(LPVOID lpParameter);
//void onPipeRead();
//static DWORD WINAPI onPipeWrite(LPVOID lpParameter);
void onPipeWrite();
static HANDLE hPipe;
static HANDLE hReadThread;
};
// TODO: 在此处引用程序需要的其他头文件
.cpp:
// NamePipe.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
HANDLE NamePipe::hPipe = NULL;
HANDLE NamePipe::hReadThread = NULL;
HANDLE cEvent = NULL;
BOOL fStop = FALSE;
//创建管道
void NamePipe::onPipeCreate(){
//创建有名管道
hPipe = CreateNamedPipe(_T("\\\\.\\pipe\\new_namedpipe"), PIPE_ACCESS_DUPLEX, 0, 1, 1024, 1024, 0, NULL);
if (INVALID_HANDLE_VALUE == hPipe){
cout << "创建命名管道失败!" << endl;
CloseHandle(hPipe);
hPipe = NULL;
return;
}
else{
cout << "创建命名管道成功!" << endl;
}
//创建匿名的人工重置事件对象
HANDLE hEvent;
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hEvent){
cout << "创建事件对象失败!" << endl;
CloseHandle(hPipe);
hPipe = NULL;
return;
}
else{
cout << "创建事件对象成功!" << endl;
}
//异步输入输出的结构体
OVERLAPPED ov;
ZeroMemory(&ov, sizeof(OVERLAPPED));
ov.hEvent = hEvent;
//等待客户端请求
if (!ConnectNamedPipe(hPipe, &ov)){
if (ERROR_IO_PENDING != GetLastError()){
cout << "等待客户端连接失败!" << endl;
CloseHandle(hPipe);
CloseHandle(hEvent);
hPipe = NULL;
return;
}
}
//等待事件对象变为有信号状态
if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE)){
cout << "等待对象失败!" << endl;
CloseHandle(hPipe);
CloseHandle(hEvent);
hPipe = NULL;
return;
}
else{
cout << "对象变为有信号状态!" << endl;
}
CloseHandle(hEvent);
return;
}
//线程读取数据
DWORD WINAPI NamePipe::onPipeRead(LPVOID lpParameter){
char buf[1000]{0};
char *data[1000]{0};
char pid[20]{0};
char *buf2 = NULL;
DWORD dwRead;
while (1)
{
//将自动重置对象设为无信号状态
WaitForSingleObject(cEvent, INFINITE);
ResetEvent(cEvent);
ZeroMemory(buf, sizeof(buf));
ZeroMemory(data, sizeof(data));
ZeroMemory(pid, sizeof(pid));
//读取数据
if (!ReadFile(hPipe, buf, 1000, &dwRead, NULL)){
cout << "服务端读取失败" << endl;
fStop = TRUE;
SetEvent(cEvent);
break;
}
else{
buf2 = strtok(buf, "\n");
strcpy(pid, buf2);
int i = 0;
while (buf2 != NULL)
{
buf2 = strtok(NULL, "\n");
if (buf2 != NULL){
data[i] = buf2;
cout << "收到来自进程[" << pid << "]的数据:" << data[i] << endl;
++i;
}
}
}
//将自动重置对象设为有信号状态
SetEvent(cEvent);
}
return 0;
}
//写入数据
void NamePipe::onPipeWrite(){
char buf[100] = "123";
DWORD dwWrite;
cout << "请输入要发送给客户端的信息:";
ZeroMemory(buf, sizeof(buf));
cin >> buf;
//写入数据
if (!WriteFile(hPipe, buf, strlen(buf) + 1, &dwWrite, NULL)){
cout << "服务端写入失败" << endl;
if (232 == GetLastError()){
cout << "客户端断开连接" << endl;
fStop = TRUE;
}
}
else{
cout << "服务端写入成功" << endl;
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
//创建并初始化管道
NamePipe np;
np.onPipeCreate();
//创建读取线程
NamePipe::hReadThread = CreateThread(NULL, 0, NamePipe::onPipeRead, NULL, 0, NULL);
if (NULL == NamePipe::hReadThread){
CloseHandle(NamePipe::hReadThread);
return -1;
}
CloseHandle(NamePipe::hReadThread);
//创建写入线程
//NamePipe::hWriteThread = CreateThread(NULL, 0, NamePipe::onPipeWrite, NULL, 0, NULL);
//if (NULL == NamePipe::hWriteThread){
// CloseHandle(NamePipe::hWriteThread);
// return -1;
//}
//CloseHandle(NamePipe::hWriteThread);
//创建匿名自动重置事件对象
cEvent = CreateEvent(NULL, FALSE, FALSE, 0);
if (!cEvent){
cout << "创建匿名自动重置事件对象失败" << endl;
return -1;
}
SetEvent(cEvent);
while (!fStop){
//将自动重置对象设为无信号状态
WaitForSingleObject(cEvent, INFINITE);
ResetEvent(cEvent);
np.onPipeWrite();
//将自动重置对象设为有信号状态
SetEvent(cEvent);
}
return 0;
}
//线程写入数据
//DWORD WINAPI NamePipe::onPipeWrite(LPVOID lpParameter){
//
// char buf[100]{0};
// DWORD dwWrite;
//
// while (1)
// {
// ZeroMemory(buf, sizeof(buf));
//
// cout << "请输入要发送给客户端的信息:";
// cin >> buf;
// if (!WriteFile(hPipe, buf, strlen(buf) + 1, &dwWrite, 0)){
// cout << "server write failed" << endl;
// break;
// }
//
// cout << "server write success" << endl;
//
// }
//
// return -1;
//}
客户端:
头文件:
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <string>
#include <cstring>
#include <iostream>
#include <process.h>
using namespace std;
class NamePipe{
public:
NamePipe(){
}
~NamePipe(){
if (hPipe){
CloseHandle(hPipe);
}
}
void onPipeConnect();
static DWORD WINAPI onPipeRead(LPVOID lpParameter);
//static DWORD WINAPI onPipeWrite(LPVOID lpParameter);
void onPipeWrite();
static HANDLE hPipe;
static HANDLE hReadThread;
};
// TODO: 在此处引用程序需要的其他头文件
.cpp:
// NamePipe2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
HANDLE NamePipe::hPipe = NULL;
HANDLE NamePipe::hReadThread = NULL;
HANDLE cEvent = NULL;
BOOL fStop = FALSE;
//连接服务器
void NamePipe::onPipeConnect(){
//判断是否可用的有名管道
if (!WaitNamedPipe(_T("\\\\.\\pipe\\new_namedpipe"), NMPWAIT_WAIT_FOREVER)){
cout << "没有可用的管道" << endl;
return;
}
else{
cout << "找到可用管道" << endl;
}
//打开可用的有名管道,与服务器通信
hPipe = CreateFile(_T("\\\\.\\pipe\\new_namedpipe"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hPipe){
cout << "打开有名管道失败" << endl;
hPipe = NULL;
return;
}
else{
cout << "打开有名管道成功" << endl;
}
}
//线程读取数据
DWORD WINAPI NamePipe::onPipeRead(LPVOID lpParameter){
char buf[100]{0};
DWORD dwRead;
while (1)
{
//将自动重置对象设为无信号状态
WaitForSingleObject(cEvent, INFINITE);
ResetEvent(cEvent);
if (ReadFile(hPipe, buf, 100, &dwRead, NULL)){
cout << "客户端读取成功,收到来自服务端的数据:" << buf << endl;
}
else{
if (ERROR_IO_PENDING == GetLastError()){
cout << "管道被占用" << endl;
}
else if (ERROR_BROKEN_PIPE == GetLastError()){
cout << "管道已断开" << endl;
}
else{
cout << "客户端读取失败" << endl;
}
fStop = TRUE;
SetEvent(cEvent);
break;
}
//将自动重置对象设为有信号状态
SetEvent(cEvent);
}
return 0;
}
//发送数据
void NamePipe::onPipeWrite(){
char buf[1000]{0};
char data[1000]{0};
char pid[20]{0};
DWORD MyPid;
DWORD dwWrite;
//清空数组
ZeroMemory(buf, sizeof(buf));
ZeroMemory(data, sizeof(data));
ZeroMemory(pid, sizeof(pid));
//打开文件,读取其中的内容
HANDLE hFile = NULL;
hFile = CreateFile(_T("F:\\Zyh\\vc++demo\\NamePipe4\\test.csv"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile){
cout << "打开文件失败" << endl;
return;
}
else{
DWORD dwRead;
ZeroMemory(buf, sizeof(buf));
if (!ReadFile(hFile, buf, sizeof(buf), &dwRead, 0)){
cout << "读取文件失败" << endl;
return;
}
else{
CloseHandle(hFile);
}
}
//获取当前进程号
MyPid = getpid();
_ultoa(MyPid, pid, 10);
//拼接进程号和数据
strcat(data, pid);
strcat(data, "\n");
strcat(data, buf);
//写入数据
if (!WriteFile(hPipe, data, strlen(data) + 1, &dwWrite, NULL)){
cout << "客户端写入数据失败" << endl;
}
else{
cout << "客户端写入数据成功" << endl;
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
//初始化并连接管道
NamePipe np;
np.onPipeConnect();
//创建读取线程
NamePipe::hReadThread = CreateThread(NULL, 0, NamePipe::onPipeRead, NULL, 0, NULL);
if (NULL == NamePipe::hReadThread){
CloseHandle(NamePipe::hReadThread);
return -1;
}
CloseHandle(NamePipe::hReadThread);
//创建写入线程
//NamePipe::hWriteThread = CreateThread(NULL, 0, NamePipe::onPipeWrite, NULL, 0, NULL);
//if (NULL == NamePipe::hWriteThread){
// CloseHandle(NamePipe::hWriteThread);
// return -1;
//}
//创建匿名自动重置事件对象
cEvent = CreateEvent(NULL, FALSE, FALSE, 0);
if (!cEvent){
cout << "创建匿名自动重置事件对象失败" << endl;
return -1;
}
SetEvent(cEvent);
while (!fStop){
//将自动重置对象设为无信号状态
WaitForSingleObject(cEvent, INFINITE);
ResetEvent(cEvent);
np.onPipeWrite();
//将自动重置对象设为有信号状态
SetEvent(cEvent);
}
system("pause");
return 0;
}
//线程写入数据
//DWORD WINAPI NamePipe::onPipeWrite(LPVOID lpParameter){
//
// char buf[100]{0};
// char pid[20]{0};
//
// DWORD MyPid;
// DWORD dwWrite;
//
// while (1)
// {
// ZeroMemory(buf, sizeof(buf));
// ZeroMemory(pid, sizeof(pid));
//
// MyPid = getpid();
// _ultoa(MyPid, pid, 10);
//
// cout << "请输入要发送给服务端的信息:";
// cin >> buf;
// strcat(buf, "@pid@");
// strcat(buf, pid);
//
// if (!WriteFile(hPipe, buf, strlen(buf) + 1, &dwWrite, 0)){
// cout << "client write failed" << endl;
// return -1;
// }
//
// cout << "client write success" << endl;
// }
//}