QProcess进程间双向通信

2 篇文章 0 订阅

记得以前写过Linux的C程序, 里面用popen打开一个子进程, 这样可以用read/write和子进程通讯, 而在子进程里则是通过从stdin读和向stdout写实现对父进程的通讯。 QProcess的底层实现用的是类似的理念。 QProcess类提供的API让父进程可以轻松地读取子进程stdout的数据, 也可以轻松地向子进程的stdin写数据。 不过这其中还是会有各种各样颇让人费解的谜团, 需要memo一下。

Test Case

两个小程序, 父进程程序名为server。 其中定义了一个QProcess, 将QProcess的readyRead信号连接到一个槽函数上, 用来接收client端stdout上的信息。 在按下“Send to Client”按钮时调用QProcess::write发送编辑框里的文字。

子进程名为client, 定义一个QFile打开stdin, 连接readyRead信号等待server端写入的数据。 按下“Send message”时向stdout写入数据。

大家觉得这个test case能如我们预料那样正常运行吗?

问题分析

这个程序从结构上来看非常简单, 如果代码不乱写不像是会出问题的样子。 实际运行的结果还是颇让人意外的, 从client端向server端发送数据很正常, 但在client里始终收不到readyRead信号!  双向交流变成了单向, 这可真让人郁闷。 仔细看QFile的文档包括QIODevice有关的描述, 看不出问题所在。 不得已只好求助专家拉, 按照专家的意见, QFile是不支持readyRead信号的。 这一点比较好理解。 但是似乎没有什么好的Qt API可以解决此问题。

Qt的API设计里没有包括最底层设备处理的类, 这个问题经常看到有人埋怨, 比如串口通讯等功能就没有直接的Qt类可用。 不过嘛笔者觉得这个不算什么问题, 像这种特别底层的东西API超简单, open->ioctl->read/write->close就完事,就算拿Qt包一层也不会更简单 , 何必多此一举呢, 如果什么功能都依赖Qt实现, 那要我们这些程序员干啥用?!

这里就需要把原来用QFile来操作stdin的代码修改成直接open/read/write/close的方式。 如果要保持原来的“有事件才动作”也不是难事, 这部分可以用Qt里的QSocketNotifier类监控fd的读写事件, 在收到信号时才去调用read/write。

主要代码

server端开进程
if(! pro )
{
pro = new QProcess(this);
connect(pro, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
connect(pro, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
connect(pro, SIGNAL(readyRead()), this, SLOT(readFromClient()));
pro->start(“./client”);
}

server端接收数据
void MainWin::readFromClient()
{
if( !pro) return;
QByteArray output = pro->readAllStandardOutput();
qWarning() }

server端发送数据
void MainWin::writeToClient()
{
if( !pro) return;
pro->write(le->text().toLatin1().constData(), le->text().length());
qWarning() text();
}

client端监控stdin的读写消息
filein.open(stdin, QIODevice::ReadOnly);
QSocketNotifier* sn = new QSocketNotifier(filein.handle(), QSocketNotifier::Read, this);
connect(sn, SIGNAL(activated(int)), this, SLOT(readFromServer(int)));

client端接收数据
void MainWin::readFromServer(int fd)
{
if(fd != filein.handle() )
return;

char buffer[256];
int count = read(filein.handle(), buffer, 256);
le->setText(“FROM SERVER:” + QString(buffer).left(count));
}

client端发送数据
void MainWin::writeToServer()
{
QFile fileout;
fileout.open(stdout, QIODevice::WriteOnly);
fileout.write(le->text().toLatin1().constData(), le->text().length()); // write to stderr
qWarning() text();
fileout.close();
}

转载至:http://blog.chinaunix.net/uid-13830775-id-97752.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值