Windows下通过命名管道传输数据(JSON)

在上一篇博客中介绍了内存映射传输大量数据的方法,但是内存映射没有一个同步机制,不进行同步的话会产生bug,这样我们可以使用命名管道做同步,因为它是阻塞机制的。它可以做小数据传输,然后用内存映射传输大量数据。命名管道中,最好设计一种协议,或者干脆用JSON。依然我们先从基础的C++建立/关闭管道开始。

#define PIPE_SIZE 1024
wchar_t* MM3D_PIPE = L"\\\\.\\pipe\\my_pipe";
HANDLE hPipe = CreateNamedPipe(MM3D_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, 0, NULL);
// do some work
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);

在建立完管道之后,我们就可以写入管道了,因为实际数据用内存映射传输,我们就可以简单的传输字符串使用。用一个while循环写入可以保证数据都写入了管道中。

// char* pdata;
// int datasize;
DWORD dwWritingSize(datasize); DWORD dwWritedSize(0);
while (dwWritingSize > 0)
{
     
	WriteFile(hPipe, &pdata[datasize - dwWritingSize], dwWritingSize, &dwWritedSize, NULL)
	dwWritingSize -= dwWritedSize;
	dwWritedSize = 0;
}

除了写,我们也可以读取管道,将数据读入buffer中。

char buffer[PIPE_SIZE] = {
      0 }; DWORD dReadSize(0);
ReadFile(hPipe, buffer, PIPE_SIZE, &dReadSize, NULL);

另一边,在Python中,我们也需要先建立管道,建立的时候必须和C++握手。依然注意,名字必须对应上。

import win32file
import win32pipe
pipename = r'\\.\\pipe\\my_pipe'
file_handle = win32file.CreateFile(pipename,win32file.GENERIC_READ | win32file.GENERIC_WRITE,win32file.FILE_SHARE_WRITE, None,win32file.OPEN_EXISTING, 0, None)
# do some work
win32file.CloseHandle(file_handle)

读取管道,data为读取到的二进制数据,需要decode,rc为收到的数据长度。

rc,data = win32file.ReadFile(file_handle, 1024)
data = bytes.decode(data)

写入管道非常简单。

data = bytes(data, encoding='utf8')
win32file.WriteFile(file_handle, data)

交流的方式建议使用JSON格式,方便好用又安全。C++需要安装JSON库。读写如下。

// int data2
Json::Value root;
root["data1"] = Json::Value("data1");
root["data2"] = Json::Value(data2);
Json::StreamWriterBuilder builder;
std::outputstr = Json::writeString(builder, root);

// char buffer[PIPE_SIZE];
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
Json::Value DevJson;
JSONCPP_STRING errs;
bool e = reader->parse(buffer, buffer + std::strlen(buffer), &DevJson, &errs);
int data = DevJson["data"].asInt();

Python中就方便很多,建议按照dict形式使用。json_str为一个json string。

import json
d_json = json.loads(json_str)
d = dict()
d['data'] = 'hello'
json_str = json.dumps(d)

你可能感兴趣的:(c++,python,json)