c++程序与c#程序通过命名管道通信

最近做的项目需要在两个程序间进行通信,server端是c++(qt)写的程序,client是c#写的程序。

之前使用QProcess通信已经测试通过了,不过是server和client都是用qt做的模拟,实际在c#中没办法接收到消息,现在重新用管道通信来实现。

server:

#include "mainwindow.h"
#include "ui_mainwindow.h"

HANDLE MainWindow::hPipe = NULL;


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    InputThread * inputThread = new InputThread;

    connect(inputThread,SIGNAL(inputedSignal(QString)),this,SLOT(onReadOutput(QString)));

    inputThread->start();

    OnPipeCreate();
}
void MainWindow::OnPipeCreate()
{
    MainWindow::hPipe = NULL;
    // 注意管道创建的参数
    // 第一个参数是管道名称,本机的话前面固定(\\\\.\\Pipe\\)必不可少
    // PIPE_ACCESS_DUPLEX|FILE_FLAG_WRITE_THROUGH|FILE_FLAG_OVERLAPPED双通道,缓存,
    MainWindow::hPipe = CreateNamedPipe(TEXT("\\\\.\\Pipe\\TestPipe"),PIPE_ACCESS_DUPLEX|FILE_FLAG_WRITE_THROUGH|FILE_FLAG_OVERLAPPED,PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT,PIPE_UNLIMITED_INSTANCES,0,0,NMPWAIT_WAIT_FOREVER,NULL);
    if(INVALID_HANDLE_VALUE == MainWindow::hPipe)
    {
        QMessageBox::about(this,"提醒","创建管道失败");
        CloseHandle(MainWindow::hPipe);
        MainWindow::hPipe = NULL;
        return;
    }

    HANDLE hEvent;
    hEvent = CreateEvent(NULL,true,false,NULL);
    if(!hEvent)
    {
        QMessageBox::about(this,"提醒","事件创建失败");
        CloseHandle(MainWindow::hPipe);
        MainWindow::hPipe = NULL;
        return;
    }
    OVERLAPPED ovlap;
    ovlap.hEvent = hEvent;
    if(!ConnectNamedPipe(hPipe,&ovlap))
    {
        if(ERROR_IO_PENDING!=GetLastError())
        {
            QMessageBox::about(this,"提醒","等待客户端连接失败");
            CloseHandle(hPipe);
            CloseHandle(hEvent);
            hPipe = NULL;
            return;
        }
    }
    if(WAIT_FAILED == WaitForSingleObject(hEvent,INFINITE))
    {
        QMessageBox::about(this,"提醒","等待对象失败");
        CloseHandle(hPipe);
        CloseHandle(hEvent);
        hPipe = NULL;
        return;
    }
    CloseHandle(hEvent);
}
void MainWindow::onReadOutput(QString str)
{
    this->ui->receiveText->append(str.trimmed());
}
void MainWindow::on_sendBtn_clicked()
{
    // server发送给client,\n必不可少
    QString str = this->ui->sendText->text()+"\n";
    char * buf;
    QByteArray ba = str.toUtf8();
    buf = ba.data();

    DWORD dwWrite;
    if(!WriteFile(MainWindow::hPipe,buf,strlen(buf),&dwWrite,NULL))
    {
        QMessageBox::about(this,"提醒","数据写入失败");
        return;
    }
}
MainWindow::~MainWindow()
{
    delete ui;
}



client:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TestCallTo
{
    public partial class FormClient : Form
    {
        SynchronizationContext syncContext = null;

        NamedPipeClientStream pipeClient = new NamedPipeClientStream(
            ".", 
            "TestPipe", 
            PipeDirection.InOut, 
             PipeOptions.Asynchronous|PipeOptions.WriteThrough,  
            TokenImpersonationLevel.None
            );  
        // 增加一个StreamWriter的定义
        StreamWriter sw = null;
        // 增加一个StreamReader的定义
        StreamReader sr = null;

        BackgroundWorker worker = new BackgroundWorker();

        public FormClient()
        {
            InitializeComponent();
            this.FormClosed += FormClient_FormClosed;
            
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.DoWork += worker_DoWork;
            worker.RunWorkerAsync();

            syncContext = SynchronizationContext.Current;
        }

        void FormClient_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (pipeClient.IsConnected)
            {
                pipeClient.Close();
            }
        }

        private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == 100)
            {
                rtbRevice.Text += e.UserState as string + "\r\n";
            }
            else if (e.ProgressPercentage == 10)
            {
                lbStatus.Text = (bool)e.UserState ? "已连接" : "未连接";
            }
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (pipeClient.IsConnected == false)
            {
                worker.ReportProgress(10, false);
                pipeClient.Connect();
                // 增加StreamWriter的初始化
                sw = new StreamWriter(pipeClient);
                sw.AutoFlush = true;
                // 增加StreamReader的初始化
                sr = new StreamReader(pipeClient);

                worker.ReportProgress(10, pipeClient.IsConnected);
            }
            while (true) 
            {
                if (sr!=null) 
                {
                    var receiveStr = sr.ReadLine();
                    // 添加到文本框
                    syncContext.Post(SetTextSafePost, receiveStr);
                }
                
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (pipeClient.IsConnected == false)
            {
                MessageBox.Show("没有连接服务端");
                return;
            }
            if (tbSend.Text.Length == 0)
            {
                return;
            }
            // 修改发送方式
            if(sw!=null)
                sw.WriteLine(tbSend.Text);

            //byte[] buffer = Encoding.Unicode.GetBytes(tbSend.Text);
            //pipeClient.Write(buffer, 0, buffer.Length);
            //pipeClient.Flush();
            //pipeClient.WaitForPipeDrain();
        }
        private void SetTextSafePost(object text) 
        {
            rtbRevice.AppendText(text.ToString());
        }
    }
}




猜你喜欢

转载自blog.csdn.net/wzj0808/article/details/80668547