使用命名管道将图像帧从服务器发送到 C# 客户端C++

Send Image Frames from C++ Server to C# Client using Named Pipe

本文关键字:服务器 C++ 客户端 管道 图像      更新时间:2023-10-16

我是IPC菜鸟。我正在尝试将图像帧从我的C++ Server发送到C# Client。我已经开始了解这一点,并做了一个小ClientServer我的C++ Server发送Hello。我看到一个相关的问题,有人告诉他们先将Image转换为Byte Array,然后以与Hello Message相同的方式发送,但我无法做到这一点。

我的基本客户端服务器代码

C++代码:

Mat image = imread("IMG_0_10_34_45_2018_1.bmp");
uchar buffer[500][500];
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
buffer[i][j] = image.at<unsigned char>(i, j);
}
}
cout << "Server Creating Pipen";
HANDLE hPipe = ::CreateNamedPipe(_T("\\.\pipe\HyperPipe"),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
PIPE_UNLIMITED_INSTANCES,
4096,
4096,
0,
NULL);
cout << "Server Created Succesfully";
ConnectNamedPipe(hPipe, NULL);
cout << "Sending Message to Client";
DWORD bytesWritten = 0;
WriteFile(hPipe, buffer, sizeof(buffer) * sizeof(uchar), &bytesWritten, NULL);
CloseHandle(hPipe);
return 0;

和 C# 代码:

static void Main(string[] args)
{
Console.WriteLine("Creating Client Pipe");
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "HyperPipe", PipeDirection.InOut);
Console.WriteLine("Pipe Created Successfully, Connecting to Server");
pipe.Connect();
Console.WriteLine("Successfully, Connected to Server");
using (StreamReader rdr = new StreamReader(pipe, Encoding.Unicode))
{
System.Console.WriteLine("Message from Server: " + rdr.ReadToEnd());
}
Console.ReadKey();
}

我还注意到,在我的C++ Server中,我必须更改PIPE_TYPE to BYTE,并且还必须更改READMODE to BYTE.我正在使用OpenCV library进行Image Processing,所以我可以轻松地Byte Array没有问题。

所以,任何人都可以告诉我如何将该Byte ArrayC++发送到C#。 或者如果可能的话,任何人都可以为我提供代码

提前致谢

更新:没有错误,但在客户端,即C# Side来自服务器的消息输出?????

要将字节数组从Server发送到Clientbuffer只需要对WriteFile函数进行微小的更改。

WriteFile(hPipe, buffer, sizeof(buffer) * sizeof(uchar), &bytesWritten, NULL);

此方法会将整个Byte Array发送到Client并且还改变了buffer

int _count = 0;
UINT8 _imageBuffer[110592];
for (int _imageRow = 0; _imageRow < _image.rows; _imageRow++)
{
for (int _imageCol = 0; _imageCol < _image.cols; _imageCol++)
{
buffer[_count] = image.at<uchar>(_imageRow, _imageCol);
_count++;
}
}

我对缓冲区数组进行了硬编码,因为我知道我的相机只会发送110592字节来创建一帧。

在客户端,只需使用Read功能。

int _imageRowSize = 288;
int _imageColSize = 384;
int _count = 0;
byte[] buffer = new byte[_imageColSize * _imageRowSize];
Image<Gray, UInt16> image = new Image<Gray, UInt16>(_imageColSize,_imageRowSize);
Console.WriteLine("Creating Client Pipe");
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "HyperPipe", 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 < 288; _imageRow++)
{
for (int _imageCol = 0; _imageCol < 384; _imageCol++)
{
try
{
image.Data[_imageRow, _imageCol, 0] = (UInt16)(buffer[_count] * 255);
}catch(Exception exception)
{
Console.WriteLine(exception);
}
_count++;
}
}
if (read <= 0)
break;
ms.Write(buffer, 0, read);
}
}           
CvInvoke.Imshow("Image", image);
}