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

标签 c# c++ opencv ipc named-pipes

我是 IPC 的菜鸟。我正在尝试将 Image Frame 从我的 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 Pipe\n";
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++ 服务器 中,我必须将 PIPE_TYPE 更改为 BYTE,并将 READMODE 更改为 BYTE。我正在使用 OpenCV 库 进行图像处理,因此我可以轻松地使 Byte Array 没有问题。

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

提前致谢

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

最佳答案

要将字节数组从Server 发送到Clientbuffer 只需在WriteFile 函数中做一些小改动是必需的。

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

此方法会将整个字节数组发送到客户端 并且还更改了 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);
        }

关于c# - 使用命名管道将图像帧从 C++ 服务器发送到 C# 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50960454/

相关文章:

c# - 在谷歌地图上绘制多个标记

c# - 邮政添加自定义 header

c# - 提高网站性能 - ASP.NET

c++ - 如何在 C++ 中遍历目录时对数据进行分组

c++ - Opencv2.3 和 Qt Creator 2.4.1 链接器错误

c# - 带委托(delegate)的 QueueUserWorkItem 不起作用,但 WaitCallBack 确实起作用

c++ - 为什么我不能在 Qt Widget 上绘制三角形

c++ - 我的模板特化将调试版本与发布版本不同,这是 gcc 错误吗?

c++ - opencv Mat 转换为 AVFrame

android - 通过修剪 OpenCV 库来减小 android apk 的大小