最近做的项目需要在两个程序间进行通信,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()); } } }