【发布时间】:2018-12-15 17:46:21
【问题描述】:
我是IPC 的新手。我尝试创建一个客户端服务器应用程序,其中我的服务器是 C++ 应用程序,而客户端是 C#。在此应用程序中,客户端将消息发送到服务器,并根据该消息服务器进行操作。
服务器基本上将图像帧发送给客户端。
使用下面的代码我可以向客户端发送单帧
我的 C++ 代码
int _count = 0;
const int _scale = 255;
int _bufferSize = ROW * COL;
UINT8 _imageBuffer[391680];
Mat _image;
std::cout << "Server Starting\n";
HANDLE hPipe1 = CreateNamedPipe(_T("\\\\.\\pipe\\HyperPipe1"),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
PIPE_UNLIMITED_INSTANCES,
4096,
4096,
0,
NULL);
std::cout << "Server Created Succesfully\n";
ConnectNamedPipe(hPipe1, NULL);
std::cout << "Sending Frame to Client";
_image = imread("C:\\Users\\Chandrapal Singh\\Desktop\\New folder\\Image.bmp", IMREAD_GRAYSCALE);
//_image.clone().convertTo(_image, CV_16U, _scale);
for (int _imageRow = 0; _imageRow < _image.rows; _imageRow++)
{
for (int _imageCol = 0; _imageCol < _image.cols; _imageCol++)
{
_imageBuffer[_count] = _image.at<UINT8>(_imageRow, _imageCol);
_count++;
}
}
DWORD bytesWritten = 0;
WriteFile(hPipe1, _imageBuffer, sizeof(_imageBuffer) * sizeof(UINT8), &bytesWritten, NULL);
我的 C# 代码
int _imageRowSize = 544;
int _imageColSize = 720;
int _count = 0;
byte[] buffer = new byte[_imageColSize * _imageRowSize];
Image<Gray, Byte> image = new Image<Gray, Byte>(_imageColSize,_imageRowSize);
Console.WriteLine("Creating Client Pipe");
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "HyperPipe1", PipeDirection.InOut);
Console.WriteLine("Pipe Created Successfully, Connecting to Server");
pipe.Connect();
Console.WriteLine("Successfully, Connected to Server");
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
_count = 0;
int read = pipe.Read(buffer, 0, buffer.Length);
for (int _imageRow = 0; _imageRow < 544; _imageRow++)
{
for (int _imageCol = 0; _imageCol < 720; _imageCol++)
{
try
{
image.Data[_imageRow, _imageCol, 0] = buffer[_count];
}catch(Exception exception)
{
Console.WriteLine(exception);
}
_count++;
}
}
CvInvoke.Imshow("Image", image);
Console.WriteLine(_count);
if (read <= 0)
break;
}
}
我想知道如何从 C# 向 C++ 发送消息,以及我的 C++ 如何连续向 C# 发送图像帧。
【问题讨论】:
-
请记住,您可以通过管道在单个消息中以原子方式发送多少数据是有限制的。查找
PIPE_BUF。 -
OP,请参阅我在 cmets 上对 @dev65 的回复。您可以只执行多个客户端请求并让服务器检查正在发送的客户端缓冲区以查看正在请求哪个帧,或者使用虚拟内存操作传递对于命名管道缓冲区来说太大的缓冲区。或者,查看未记录的用于共享内存部分的 ALPC 机制(Microsoft 在内部依赖于 csrss 等子系统)。对您来说,客户端请求(多次)或虚拟内存方法(使用命名管道)可能是理想的。
-
对于虚拟内存的操作方法,你不需要做任何复杂的事情。您可以使用 VirtualAllocEx 和 WriteProcessMemory,然后通过命名管道传递在客户端进程的虚拟内存上下文中存储大缓冲区的指针 - 该地址将是从 VirtualAllocEx 返回的地址(将在客户端进程的虚拟内存中有效仅,因为您要将句柄传递给进程句柄参数的客户端进程)。
标签: c# c++ winapi pipe message