Qt下使用fork创建进程并使用socket通信

栏目: C++ · 发布时间: 5年前

把最近工作总结下。

之前在嵌入 python 解释器的过程中,我们没有处理这样一种情况:当 Python 解释器正在执行一个阻塞操作 ( 比如 socket server 在监听一个客户端连入 ) ,这时我们需要终止解释器的运行,该如何操作呢?

在Qt线程中不容易实现该功能,如果在 socket 监听时终止 python 解释器,那么再次运行时端口就会显示被占用,因为资源没有清理。为了解决这种情况,我们让解释器运行在一个进程中。这样在需要停止时,我们可以发送 kill 信号终止进程。

老规矩,接下来上码:

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include

#include

#include

#include

#include    //close head file

#include

#include

#include

#include

int childProcessId = -1;

int client_sockfd;

void sigint(int);

void sigint(int signal)

{

if(SIGINT == signal)

{

qDebug() << "My DADDY has Killed me!!!";

exit(0);

}

}

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

//tcp server

processServer = new QTcpServer();

connect(processServer, SIGNAL(newConnection()),

this, SLOT(slot_recvClientConnect()));

if(!processServer->listen(QHostAddress::Any, 8866))

{

// 监听本地主机的 88 66 端口,如果出错就输出错误信息,并关闭

qDebug() <<"error message"<errorString();

processServer->close();

}

///////////////client

struct sockaddr_in remote_addr; // 服务器端网络地址结构体

memset(&remote_addr,0,sizeof(remote_addr)); // 数据初始化 -- 清零

remote_addr.sin_family=AF_INET; // 设置为 IP 通信

remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");// 服务器 IP 地址

remote_addr.sin_port=htons(8866); // 服务器端口号

/* 创建客户端套接字 --IPv4 协议,面向连接通信, TCP 协议 */

if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)

{

perror("socket");

return;

}

/* 将套接字绑定到服务器的网络地址上 */

if(::connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)

{

perror("connect");

return;

}

}

MainWindow::~MainWindow()

{

processServer->close();

delete ui;

delete processServer;

}

void MainWindow::slot_recvClientConnect()

{

qDebug() << "accept connect";

clientConnect = processServer->nextPendingConnection();

connect(clientConnect, SIGNAL(readyRead()),

this, SLOT(slot_readClientData()));

}

void MainWindow::slot_readClientData()

{

QString str;

str = clientConnect->readAll();

clientConnect->write("hello");

qDebug() << "client data>>:" << str  ;

}

void MainWindow::on_pbn_start_clicked()

{

pid_t pid;

pid = fork();

if(pid < 0)

{

qDebug() << "creat process faild!";

}

else if((pid_t)0 == pid)  //child process,pid is child pid

{

signal(SIGINT, sigint);

qDebug() << "this is client proccess!";

char buf1[] = "socket client";

while(1)

{

send(client_sockfd,buf1,strlen(buf1),0);

QThread::sleep(3);

}

}

else                  // parent process

{

childProcessId = pid;

qDebug() << "child process pid is " << childProcessId;

}

}

void MainWindow::on_pbn_stop_clicked()

{

if(-1 != childProcessId)

{

pid_t pidClear;

kill(childProcessId, SIGINT);

QThread::usleep(500);

do{

pidClear = waitpid(childProcessId,NULL,WNOHANG);

if(-1 == pidClear)

{

qDebug() << "clear  error!!!";

}

if(childProcessId == pidClear)

{

qDebug() << "clear   success!!!";

}

QThread::usleep(500);

}while(0 == pidClear);

childProcessId = -1;

}

}

程序环境是ubuntu + Qt。

简单介绍下程序的主体构成:构造函数中使用c创建客户端,使用 Qt 的类创建服务器。

界面点击 start 按钮时,使用 fork 创建子进程,在进程中客户端向服务器发送数据。点击 stop 按钮时,父进程向子进程发出 kill 信号,由于子进程注册了中断信号,所以会执行信号函数中的操作。之后父进程使用  waitpid(childProcessId,NULL,WNOHANG) 等待清理子进程,之后进程资源被释放。如果 python 解释器运行在进程中,那么 python 解释器也会被中断,资源被清理故而不会被占用。 Python 重定向信息输出也可通过 socket 发送出来。

程序运行效果:

Qt下使用fork创建进程并使用socket通信

在子进程被中断前,先进入信号函数。之后由父进程清理子进程资源。

如果大家觉得还阔以,欢迎大家后台留言交流。

Qt下使用fork创建进程并使用socket通信


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Design Accessible Web Sites

Design Accessible Web Sites

Jeremy Sydik / Pragmatic Bookshelf / 2007-11-05 / USD 34.95

It's not a one-browser web anymore. You need to reach audiences that use cell phones, PDAs, game consoles, or other "alternative" browsers, as well as users with disabilities. Legal requirements for a......一起来看看 《Design Accessible Web Sites》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具