共计 5113 个字符,预计需要花费 13 分钟才能阅读完成。
Qt 中的 TCP 服务端和客户端互发音讯
作者:hackett
微信公众号:加班猿
废话不多说,上演示成果
因为咱们用到 socket 跟Lamda表达式,所以工程.pro 文件须要增加对应的库
为了不便,main.cpp 中让程序显示两个 Widget 窗口, 程序运行起来就能够测试
ServerWidget w;
w.show();
ClientWidget w2;
w2.show();
一、服务端
服务端的 UI 界面布局:
2 个 PushButton(send,close)
2 个 textEdit(发送内容,接管内容)
新建一个监听套接字,监听端口号为 9999 的 IP,期待连贯,有连贯过去提醒胜利连贯同时服务端读就绪
// 监听套接字,指定父对象,让其主动回收空间
tcpServer = new QTcpServer(this);
tcpServer->listen(QHostAddress::Any, 9999);
setWindowTitle(“ 服务器: 9999”);
//newConnection 代表有新的连贯
connect(tcpServer, &QTcpServer::newConnection,
[=]()
{
// 取出建设好连贯的套接字
tcpSocket = tcpServer->nextPendingConnection();
// 获取对方的 IP 和端口
QString ip = tcpSocket->peerAddress().toString();
quint16 port = tcpSocket->peerPort();
QString temp = QString(“[%1:%2]: 胜利连贯 ”).arg(ip).arg(port);
ui->textEditRead->setText(temp);
//readyRead 代表读就绪
connect(tcpSocket, &QTcpSocket::readyRead,
[=]()
{
// 从通信套接字中取出内容
QByteArray array = tcpSocket->readAll();
ui->textEditRead->append(array);
}
);
}
);
二、客户端
客户端的 UI 界面布局:
3 个 PushButton(connect,send,close)
2 个 lineEdit(端口号,IP)
2 个 textEdit(发送内容,接管内容)
客户端连贯按钮被动与服务端建设连贯
void ClientWidget::on_buttonConnect_clicked()
{
// 获取服务器 ip 和端口
QString ip = ui->lineEditIP->text();
qint16 port = ui->lineEditPort->text().toInt();
// 被动和服务器建设连贯
tcpSocket->connectToHost(QHostAddress(ip), port);
}
连贯胜利后会触发 connected,提醒 ” 胜利和服务器建设好连贯 ” 同时客户端读就绪
// 调配空间,指定父对象
tcpSocket = new QTcpSocket(this);
setWindowTitle(“ 客户端 ”);
connect(tcpSocket, &QTcpSocket::connected,
[=]()
{
ui->textEditRead->setText(“ 胜利和服务器建设好连贯 ”);
}
);
connect(tcpSocket, &QTcpSocket::readyRead,
[=]()
{
// 获取对方发送的内容
QByteArray array = tcpSocket->readAll();
// 追加到编辑区中
ui->textEditRead->append(array);
}
);
源码
main.cpp
#include “serverwidget.h”
#include <QApplication>
#include “clientwidget.h”
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ServerWidget w;
w.show();
ClientWidget w2;
w2.show();
return a.exec();
}
serverwidget.cpp
#include “serverwidget.h”
#include “ui_serverwidget.h”
#include <QDebug>
ServerWidget::ServerWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ServerWidget)
{
ui->setupUi(this);
tcpServer = NULL;
tcpSocket = NULL;
// 监听套接字,指定父对象,让其主动回收空间
tcpServer = new QTcpServer(this);
tcpServer->listen(QHostAddress::Any, 9999);
setWindowTitle(“ 服务器: 9999”);
//newConnection 代表有新的连贯
connect(tcpServer, &QTcpServer::newConnection,
[=]()
{
// 取出建设好连贯的套接字
tcpSocket = tcpServer->nextPendingConnection();
// 获取对方的 IP 和端口
QString ip = tcpSocket->peerAddress().toString();
quint16 port = tcpSocket->peerPort();
QString temp = QString(“[%1:%2]: 胜利连贯 ”).arg(ip).arg(port);
ui->textEditRead->setText(temp);
//readyRead 代表读就绪
connect(tcpSocket, &QTcpSocket::readyRead,
[=]()
{
// 从通信套接字中取出内容
QByteArray array = tcpSocket->readAll();
ui->textEditRead->append(array);
}
);
}
);
}
ServerWidget::~ServerWidget()
{
delete ui;
}
void ServerWidget::on_buttonSend_clicked()
{
if(NULL == tcpSocket)
{
return;
}
// 获取编辑区内容
QString str = ui->textEditWrite->toPlainText();
// 给对方发送数据,应用套接字是 tcpSocket
tcpSocket->write(str.toUtf8().data());
}
void ServerWidget::on_buttonClose_clicked()
{
if(NULL == tcpSocket)
{
return;
}
// 被动和客户端端口连贯
tcpSocket->disconnectFromHost();
tcpSocket->close();
tcpSocket = NULL;
}
serverwidget.h
#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H
#include <QWidget>
#include <QTcpServer> // 监听套接字
#include <QTcpSocket> // 通信套接字
namespace Ui {
class ServerWidget;
}
class ServerWidget : public QWidget
{
Q_OBJECT
public:
explicit ServerWidget(QWidget *parent = 0);
~ServerWidget();
private slots:
void on_buttonSend_clicked();
void on_buttonClose_clicked();
private:
Ui::ServerWidget *ui;
QTcpServer *tcpServer; // 监听套接字
QTcpSocket *tcpSocket; // 通信套接字
};
#endif // SERVERWIDGET_H
clientwidget.cpp
#include “clientwidget.h”
#include “ui_clientwidget.h”
#include <QHostAddress>
ClientWidget::ClientWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ClientWidget)
{
ui->setupUi(this);
tcpSocket = NULL;
// 调配空间,指定父对象
tcpSocket = new QTcpSocket(this);
setWindowTitle(“ 客户端 ”);
connect(tcpSocket, &QTcpSocket::connected,
[=]()
{
ui->textEditRead->setText(“ 胜利和服务器建设好连贯 ”);
}
);
connect(tcpSocket, &QTcpSocket::readyRead,
[=]()
{
// 获取对方发送的内容
QByteArray array = tcpSocket->readAll();
// 追加到编辑区中
ui->textEditRead->append(array);
}
);
}
ClientWidget::~ClientWidget()
{
delete ui;
}
void ClientWidget::on_buttonConnect_clicked()
{
// 获取服务器 ip 和端口
QString ip = ui->lineEditIP->text();
qint16 port = ui->lineEditPort->text().toInt();
// 被动和服务器建设连贯
tcpSocket->connectToHost(QHostAddress(ip), port);
}
void ClientWidget::on_buttonSend_clicked()
{
// 获取编辑框内容
QString str = ui->textEditWrite->toPlainText();
// 发送数据
tcpSocket->write(str.toUtf8().data());
}
void ClientWidget::on_buttonClose_clicked()
{
// 被动和对方断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close();
}
clientwidget.h
#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H
#include <QWidget>
#include <QTcpSocket> // 通信套接字
namespace Ui {
class ClientWidget;
}
class ClientWidget : public QWidget
{
Q_OBJECT
public:
explicit ClientWidget(QWidget *parent = 0);
~ClientWidget();
private slots:
void on_buttonConnect_clicked();
void on_buttonSend_clicked();
void on_buttonClose_clicked();
private:
Ui::ClientWidget *ui;
QTcpSocket *tcpSocket; // 通信套接字
};
#endif // CLIENTWIDGET_H
如果你感觉文章还不错,记得 ”点赞关注“
关注我的微信公众号【加班猿】能够获取更多内容