搭建基于QT的TCP服务器与客户端
1、实现功能
1、服务器和客户端能够建立连接
2、服务器可以给客户端发送信息
3、客户端可以给服务器发送信息
2、server
2-1、widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void readData();
private slots:
void on_send_btn_clicked();
private:
Ui::Widget *ui;
QTcpServer *server;
QTcpSocket *client;
};
#endif // WIDGET_H
2-2、widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//设置一下窗口标题
this->setWindowTitle("server");
//实例化服务器对象
this->server = new QTcpServer(this);
//创建监听队列并邦定ip和port
//本地主机ip,端口号为1024~49151
this->server->listen(QHostAddress("192.168.12.47"), 9999);
//等待客户端连接,做信号与槽函数关联
connect(this->server, &QTcpServer::newConnection, this, [=]()
{
this->client = this->server->nextPendingConnection();
//得到了客户端,就可以进行通信
connect(this->client, &QTcpSocket::readyRead, this, &Widget::readData);
});
}
Widget::~Widget()
{
delete ui;
}
//从客户端读数据
void Widget::readData()
{
//从客户端中读数据
QByteArray data = this->client->readAll();
//读到的数据添加到recv_edit中
this->ui->recv_edit->append(data);
}
//给客户端写数据
void Widget::on_send_btn_clicked()
{
//获取到需要发送给客户端的数据
QString data = this->ui->send_edit->text();
//发送给客户端
this->client->write(data.toUtf8());
//清空输入框
this->ui->send_edit->clear();
}
2-3、widget.ui
3、client
3-1、widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_connect_btn_clicked();
void on_send_btn_clicked();
public slots:
void readData();
private:
Ui::Widget *ui;
QTcpSocket *client;
int flag;
int src_size;
QByteArray src_data;
};
#endif // WIDGET_H
3-2、widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#include <QMessageBox>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("client");
this->flag = 0;
this->src_size = 0;
this->src_data.clear();
//实例化客户端套接字对象
this->client = new QTcpSocket(this);
//成功连接与否,信号与槽的关联
connect(this->client, &QTcpSocket::connected, this, [=]()
{
QMessageBox::information(this, "提示", "成功建立连接");
});
//进行通信,读是被动的,需要做信号与槽关联
connect(this->client, &QTcpSocket::readyRead, this, &Widget::readData);
}
Widget::~Widget()
{
delete ui;
}
//连接服务器
void Widget::on_connect_btn_clicked()
{
//获取ip和port
QString ip = this->ui->ip_edit->text();
uint port = this->ui->port_edit->text().toUInt();
//连接服务器
this->client->connectToHost(QHostAddress(ip), port);
}
//从客户端读数据
void Widget::readData()
{
// //从客户端中读数据
// QByteArray data = this->client->readAll();
// //读到的数据添加到recv_edit中
// this->ui->recv_edit->append(data);
char buf[256] = {0};
if(this->flag == 0)
{
this->client->read(buf, 256); //FILE_SIZE#文件大小
QStringList info = QString(buf).split("#");
if(info.front() == "FILE_SIZE")
{
//获取到图片文件的大小
this->src_size = info.back().toInt();
this->flag = 1;
}
}
else if(this->flag == 1) //开始接收真正的图像数据
{
QByteArray data = this->client->readAll();
//保存下来
this->src_data.append(data);
if(this->src_data.size() == this->src_size)
{
//下载成功
QPixmap pix;
pix.loadFromData(this->src_data);
this->ui->label->setPixmap(pix.scaled(this->ui->label->size()));
this->flag = 0;
this->src_size = 0;
this->src_data.clear();
}
}
}
//给客户端写数据
void Widget::on_send_btn_clicked()
{
//获取到需要发送给客户端的数据
QString data = this->ui->send_edit->text();
//发送给客户端
this->client->write(data.toUtf8());
//清空输入框
this->ui->send_edit->clear();
}