利用 QTcpSocket 实现的进程间通信

简介

做一个简答的进程间通信的原型,主要是为了了解进程间通信的一些原理
本文是利用 QTcpSocket 来实现的。

主要步骤

实现之后的UI界面如下,主要步骤有一下几步:
1、ServerSocket 点击建立连接(此时 ServerSocket 开始监听端口为 5555 的其他程序)
2、WorkerSocket 点击连接服务器(通过制定的IP地址和端口主动连接服务器)
3、连接之后可以开始互相发送消息。
在这里插入图片描述

代码实现

列出了关键的几个文件

// ServerSocket.h
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_ServerSocket.h"
#include <QtNetwork/QTcpServer>

class ServerSocket : public QMainWindow
{
    Q_OBJECT

public:
    ServerSocket(QWidget *parent = Q_NULLPTR);

private slots:
	void OnBtnInitSocket();   // 开始监听worker
	void OnBtnSendClick();
	void ServerReadData();
	void ServerNewConnection();     // 和work端建立连接时
	void ServerDisConnection();     // 和work端断开连接时

private:
    Ui::ServerSocketClass ui;

	QTcpServer *m_TCPServer;
	QTcpSocket *m_TCPSocket;
};
// ServerSocket.cpp
#include "ServerSocket.h"
#include <QtWidgets/QMessageBox>
#include <QtNetwork/QTcpSocket>

struct DataHeader
{
    char magic;
    int length;
    int intlength;
};

ServerSocket::ServerSocket(QWidget *parent)
    : QMainWindow(parent), m_TCPServer(nullptr), m_TCPSocket(nullptr)
{
    ui.setupUi(this);

    ui.lineEdit_port->setText("5550");
    connect(ui.btn_initPort, SIGNAL(clicked()), this, SLOT(OnBtnInitSocket()));
    connect(ui.btn_send, SIGNAL(clicked()), this, SLOT(OnBtnSendClick()));
}

void ServerSocket::OnBtnInitSocket()
{
	m_TCPServer = new QTcpServer();
	int port = ui.lineEdit_port->text().toInt();
	if (!m_TCPServer->listen(QHostAddress::Any, port))     // 监听信息(监听的机器的IP地址和端口)
	{
		QMessageBox::information(this, "QT TPC", "listen falure !");
		return;
	}
	else
	{
		QMessageBox::information(this, "QT TPC", "listen succeed !");
	}
	// 当监听到信号的时候会发出newConnection() 信号
	connect(m_TCPServer, SIGNAL(newConnection()), this, SLOT(ServerNewConnection()));
}

void ServerSocket::ServerNewConnection()
{
	m_TCPSocket = m_TCPServer->nextPendingConnection();
	if (!m_TCPSocket)
	{
		QMessageBox::information(this, "QT TPC", "connect falure !");
		return;
	}
	else
	{
		QMessageBox::information(this, "QT TPC", "connect succeed");
		connect(m_TCPSocket, SIGNAL(readyRead()), this, SLOT(ServerReadData()));
		connect(m_TCPSocket, SIGNAL(disconnected()), this, SLOT(ServerDisConnection()));
	}
}

void ServerSocket::ServerReadData()
{
    QByteArray resArray = m_TCPSocket->read(1024);
    char* pCharRes;
    QDataStream stream(&resArray, QIODevice::ReadOnly);
    stream >> pCharRes;
	if (strlen(pCharRes/*buffer*/) > 0)
	{
		QString showNsg = pCharRes/*buffer*/;
		ui.textBrowser_receive->append(showNsg);
	}
	else
	{
		QMessageBox::information(this, "QT TCP", "Data error");
		return;
	}
}

void ServerSocket::ServerDisConnection()
{
    QMessageBox::information(this, "QT TCP", "Disconnect from the client");
    return;
}

void ServerSocket::OnBtnSendClick()
{
    char sendMsgChar[1024] = { 0 };
    QString sendMsg = ui.textEdit_send->toPlainText();
    if (sendMsg.isEmpty())
    {
        QMessageBox::information(this, "QT TCP", "Data is empty, please enter data");
        return;
    }

    QByteArray block;
    QDataStream stream(&block, QIODevice::WriteOnly);
    stream.setVersion(QDataStream::Qt_5_5);

    stream << sendMsg.toStdString().c_str();
    
    if (m_TCPSocket->isValid())
    {
        int sendRe = m_TCPSocket->write(block);
        if (-1 == sendRe)
        {
            QMessageBox::information(this, "QT TCP", "Failed to send data");
        }
    }
    else
    {
        QMessageBox::information(this, "QT TCP", "Invalid socket");
    }
}
// WorkerSocket.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_WorkerSocket.h"
#include <QtNetwork/QTcpSocket>


class WorkerSocket : public QMainWindow
{
    Q_OBJECT

public:
    WorkerSocket(QWidget *parent = Q_NULLPTR);

    void JumpToServer();

private slots:
	void OnConnectBtnClicked();  // 点击连接的按钮,开始连接服务器

	void OnSendBtnClicked();     // 点击发送按钮,发送消息

	void WorkerReceiveData();    // 接收到消息,解析数据

private:
    Ui::WorkerSocketClass* ui;

	QTcpSocket *m_clientSocket;
};
// WorkerSocket.cpp
#include "WorkerSocket.h"
#include <QtWidgets/QMessageBox>
#include <QProcess>
#include <QDebug>
#include <QTextBrowser>


WorkerSocket::WorkerSocket(QWidget *parent)
    : QMainWindow(parent),
    ui(new Ui::WorkerSocketClass())   // 成员指针在使用之前需要先初始化
{
    ui->setupUi(this);

	ui->lineEdit_IP->setText("10.4.38.33");    // 输入服务端机器的IP地址
	ui->lineEdit_port->setText("5555");         // 保证服务端和工作端的端口一致即可

	connect(ui->btn_connect, SIGNAL(clicked()), this, SLOT(OnConnectBtnClicked()));
	connect(ui->btn_send, SIGNAL(clicked()), this, SLOT(OnSendBtnClicked()));
}

// 与服务器建立连接后
void WorkerSocket::OnConnectBtnClicked()
{
	m_clientSocket = new QTcpSocket();
	QString ip = ui->lineEdit_IP->text();
	int port = ui->lineEdit_port->text().toInt();
	m_clientSocket->connectToHost(ip, port);
	if (!m_clientSocket->waitForConnected(10000))
	{
		QMessageBox::information(this, "QT TCP", "connect failure!");
		return;
	}
    QMessageBox::information(this, "QT TCP", "connect succeed!");
	connect(m_clientSocket, SIGNAL(readyRead()), this, SLOT(WorkerReceiveData()));
}

// 发送消息
void WorkerSocket::OnSendBtnClicked()
{
    QString sendMsg = ui->textEdit_send->toPlainText();

    QByteArray resArray;
    QDataStream stream(&resArray, QIODevice::WriteOnly);

    stream << sendMsg.toStdString().c_str();

    qint64 sendRes = m_clientSocket->write(resArray);
}

// 接受到服务端传过来的数据
void WorkerSocket::WorkerReceiveData()
{
    QByteArray resArray = m_clientSocket->readAll();

    QDataStream stream(&resArray, QIODevice::ReadOnly);

    char* pCharRes;
    stream >> pCharRes;

    if (strlen(pCharRes/*buffer*/) > 0)
    {
        QString showNsg = pCharRes/*buffer*/;
        ui->textBrowser_receive->append(showNsg);
    }
    else
    {
        QMessageBox::information(this, "QT TCP", "Data error");
        return;
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值