简介
做一个简答的进程间通信的原型,主要是为了了解进程间通信的一些原理
本文是利用 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;
}
}