此篇是介绍TCP的服务器端和客户端的流程,是根据视频写的
pro文件添加 network 模块
https://www.bilibili.com/video/BV1yt411d7E4?p=59
服务器端:
主要思路: 需要用到两个套接字 QTcpServer;//监听套接字
QTcpSocket;//通信套接字,里面存储的是客户端的信息
具体的步骤为: 建立监听套接字,监听;如果客户端连接成功后,服务器端会触发newConnection信号,在此信号槽内处理: 获取通信套接字,获取发送内容。
在关闭时,断开与客户端的连接
具体内容:
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QTcpServer;//监听套接字
class QTcpSocket;//通信套接字
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_send_btn_clicked();
void on_close_btn_clicked();
private:
Ui::Widget *ui;
QTcpServer *m_pTcpServer;//监听套接字 指针要动态内存分配
QTcpSocket *m_pTcpSocket;//通信套接字
void InitCtrl();
};
#endif // WIDGET_H
cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
//https://www.bilibili.com/video/BV1yt411d7E4?p=59&spm_id_from=pageDriver
#pragma execution_character_set("utf-8")
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
InitCtrl();
}
Widget::~Widget()
{
delete ui;
}
void Widget::InitCtrl()
{
setWindowTitle("服务器端");
m_pTcpServer = NULL;
m_pTcpSocket = NULL;
//创建监听套接字
m_pTcpServer = new QTcpServer(this);
//监听
m_pTcpServer->listen(QHostAddress::Any, 8888);
//连接
connect(m_pTcpServer,&QTcpServer::newConnection,this,[=](){
//取出建立好连接的套接字
m_pTcpSocket = m_pTcpServer->nextPendingConnection();
//获取对方的ip和端口
QString str = m_pTcpSocket->peerAddress().toString();
qint16 nport = m_pTcpSocket->peerPort();
QString strr = QString("[%1 : %2 ] connect ok").arg(str).arg(nport);
qDebug() << strr<<endl;
ui->textEditRead->setText(strr);
//取出来后采用
connect(m_pTcpSocket, &QTcpSocket::readyRead,this,[=](){
//通信套接字中取出内容
QByteArray array = m_pTcpSocket->readAll();
ui->textEditRead->append(array);
});
});
//还没有赋值,会导致程序启动不起来
// connect(m_pTcpSocket, &QTcpSocket::readyRead,this,[=](){
// //通信套接字中取出内容
// QByteArray array = m_pTcpSocket->readAll();
// ui->textEditRead->append(array);
// });
}
void Widget::on_send_btn_clicked()
{
if(m_pTcpSocket == NULL)
{
return;
}
QString str = ui->textEditWrite->toPlainText();
//m_pTcpSocket->write(str.toUtf8().data(),str.length());
//m_pTcpSocket->write(str.toUtf8().data(), str.length());//用此时,给客户端发的数据乱码
m_pTcpSocket->write(str.toUtf8().data());
}
void Widget::on_close_btn_clicked()
{
if(m_pTcpSocket == NULL)
{
return;
}
//tcp主动断开和客户端端口连接
m_pTcpSocket->disconnectFromHost();
m_pTcpSocket->close();
m_pTcpSocket = NULL;
}
客户端
主要用到通信套接字 QTcpSocket, 里面存的是服务器的信息
在初始化时,创建通信套接字,在connect按钮下,根据ip和端口号,
主动和服务器建立连接,同时会触发connected信号。
在与服务器创建连接后,可以接收服务器发送的数据readyRead
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QTcpSocket;//通信套接字
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_clost_btn_clicked();
void on_send_btn_clicked();
private:
Ui::Widget *ui;
void InitTCP();
QTcpSocket *m_pTcpSocket;
};
#endif // WIDGET_H
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QTcpServer>
#include <QTcpSocket>
#pragma execution_character_set("utf-8")
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
InitTCP();
}
Widget::~Widget()
{
delete ui;
}
void Widget::InitTCP()
{
setWindowTitle("客户端");
m_pTcpSocket = NULL;
m_pTcpSocket = new QTcpSocket(this);
connect(ui->connect_btn,&QPushButton::clicked,this,[=](){
QString strIP = ui->lineEditIP->text();
qint16 nport = ui->lineEditPort->text().toInt();
//主动和服务器建立连接
m_pTcpSocket->connectToHost(QHostAddress(strIP), nport);
//在此处建立收
connect(m_pTcpSocket,&QTcpSocket::readyRead,this,[=](){
QString str = m_pTcpSocket->readAll();
ui->textEditRead->append(str);
});
});
connect(m_pTcpSocket,&QTcpSocket::connected,this,[=](){
ui->textEditRead->append("和服务器建立连接");
});
}
void Widget::on_clost_btn_clicked()
{
//主动和服务器断开连接
if(m_pTcpSocket == NULL)
{
return ;
}
m_pTcpSocket->disconnectFromHost();
}
void Widget::on_send_btn_clicked()
{
QString str =ui->textEdiWrite->toPlainText();
m_pTcpSocket->write(str.toUtf8().data());
}
注意:
//m_pTcpSocket->write(str.toUtf8().data(), str.length());//用此时,给客户端发的数据乱码
m_pTcpSocket->write(str.toUtf8().data());//必须用此句