Qt之tcp的简单使用

今天需要做一个服务器端的tcp通信

因为之前没有用过qt的方法,只用过C语言版本的,所以干脆客户端和服务器端都查了下,做个笔记。

先上代码

客户端.h

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void on_pushButton_Connect_clicked();

    void on_pushButton_Send_clicked();

    void socket_Read_Data();

    void socket_Disconnected();


private:
    Ui::MainWindow *ui;
    QTcpSocket *socket;
};

#endif // MAINWINDOW_H

客户端.cpp

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    socket = new QTcpSocket();

    //连接信号槽
    QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
    QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

    ui->pushButton_Send->setEnabled(false);
    ui->lineEdit_IP->setText("192.168.0.109");
    ui->lineEdit_Port->setText("8088");

}

MainWindow::~MainWindow()
{
    delete this->socket;
    delete ui;
}

void MainWindow::on_pushButton_Connect_clicked()
{
    if(ui->pushButton_Connect->text() == tr("connect"))
    {
        int port;
        //获取端口号
        port = ui->lineEdit_Port->text().toInt();

        //取消已有的连接
        socket->abort();
        //连接服务器
        socket->connectToHost(ui->lineEdit_IP->text(), port);

        //等待连接成功
        if(!socket->waitForConnected(30000))
        {
            qDebug() << "Connection failed!";
            return;
        }
        qDebug() << "Connect successfully!";

        //发送按键使能
        ui->pushButton_Send->setEnabled(true);
        //修改按键文字
        ui->pushButton_Connect->setText("断开连接");
    }
    else
    {
        //断开连接
        socket->disconnectFromHost();
        //修改按键文字
        ui->pushButton_Connect->setText("连接");
        ui->pushButton_Send->setEnabled(false);
    }
}

void MainWindow::on_pushButton_Send_clicked()
{
    qDebug() << "Send: " << ui->textEdit_Send->toPlainText();
     //获取文本框内容并以ASCII码形式发送
    socket->write(ui->textEdit_Send->toPlainText().toLocal8Bit());
    socket->flush();
}

void MainWindow::socket_Read_Data()
{
    //读取缓冲区数据
    QByteArray buffer = socket->readAll();
    if(!buffer.isEmpty())
    {
        QString str = ui->textEdit_Recv->toPlainText().fromLocal8Bit(buffer);
        qDebug() << "recv data = " << str;
        //刷新显示
        ui->textEdit_Recv->setText(str);
    }
}

void MainWindow::socket_Disconnected()
{
    //发送按键失能
    ui->pushButton_Send->setEnabled(false);
    //修改按键文字
    ui->pushButton_Connect->setText("连接");
    qDebug() << "Disconnected!";
}

服务端.h

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class TcpServer; }
QT_END_NAMESPACE

class TcpServer : public QWidget
{
    Q_OBJECT

public:
    TcpServer(QWidget *parent = nullptr);
    ~TcpServer();
    void setHostAddress(QString address){m_hostAddress=address;}
    void setTcpServerPort(int port){m_tcpServerPort=port;}

protected slots:
    void server_New_Connect();
    void socket_Read_Data();
    void socket_Disconnected();

private slots:
    void on_writeBtn_clicked();
    void on_setListen_clicked();
    void on_setAdd_clicked();
    void on_setPort_clicked();

private:
    Ui::TcpServer *ui;

    QTcpServer* mServer;
    QTcpSocket* mSocket;

    QString m_hostAddress = "192.168.0.100";//"192.168.0.109";
    int m_tcpServerPort = 8000;//8080;
};
#endif // TCPSERVER_H

服务端.cpp

#include "tcpserver.h"
#include "ui_tcpserver.h"

TcpServer::TcpServer(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::TcpServer)
{
    ui->setupUi(this);

    //1.创建一个tcpServer对象
    mServer = new QTcpServer(this);
    mSocket= new QTcpSocket;

    //2.监听一个端口,使得客户端可以使用这个端口访问服务器
//    mServer->listen(QHostAddress::Any, 8080);

    //3.链接信号槽
    connect(mServer,&QTcpServer::newConnection,this,&TcpServer::server_New_Connect);
}

TcpServer::~TcpServer()
{
    delete ui;
}

void TcpServer::server_New_Connect()
{
    //获取客户端连接
    mSocket = mServer->nextPendingConnection();
    qDebug() << "A Client connect!";
    //连接QTcpSocket的信号槽,以读取新数据
    QObject::connect(mSocket, &QTcpSocket::readyRead, this, &TcpServer::socket_Read_Data);
    QObject::connect(mSocket, &QTcpSocket::disconnected, this, &TcpServer::socket_Disconnected);
}

void TcpServer::socket_Read_Data()
{
    //读取缓冲区数据
    QByteArray buffer = mSocket->readAll();
    if(!buffer.isEmpty())
    {
        ui->recvData->clear();
        ui->recvData->setText(QString::fromLocal8Bit(buffer));
    }
}

void TcpServer::socket_Disconnected()
{
    //发送按键失能
    qDebug() << "Disconnected!";
}

void TcpServer::on_writeBtn_clicked()
{
    QString buf = "hello tcp " + ui->recvData->toPlainText();
//    char *buffer = buf.toLatin1().data();
    mSocket->write(buf.toLocal8Bit());
//    qDebug() << "server wirte buffer = " << buffer;
    mSocket->flush();
}


void TcpServer::on_setListen_clicked()
{
    qDebug() << "start to listen";
    mServer->listen(QHostAddress::Any, 8088);
}


void TcpServer::on_setAdd_clicked()
{
    setHostAddress("192.168.0.109");
    qDebug() << "set host address: " << "192.168.0.109";
}


void TcpServer::on_setPort_clicked()
{
    setTcpServerPort(8088);
    qDebug() << "set host port: " << 8088;
}

 

 因为只是做个demo,不需要太过细节,所以服务端返回的数据就是在收到客户端数据的基础上加了hello tcp;

这个demo只能做一个简单的小框架。

qt的封装,利用信号和槽使tcp通讯十分方便

客户端

  1. socket = new QTcpSocket();//申请socket对象
  2. socket->connectToHost(ip, port);//链接已经在监听的服务器ip和端口
  3. socket->write();//对已经socket写入数据
  4. QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);//如果服务器端发送过来数据,就会触发readyRead这个信号,我们在客户端只需要完成他的槽函数里面的操作即可,发送接收数据要注意数据格式,防止中文出现乱码

服务器 

1.需要同时用到QTcpServer类和QTcpSocket    
mServer = new QTcpServer;
mSocket= new QTcpSocket;
2.监听一个端口,使得客户端可以使用这个端口访问服务器
mServer->listen(QHostAddress::Any, 8080);

3.链接信号槽    connect(mServer,&QTcpServer::newConnection,this,&TcpServer::server_New_Connect);

 当有用户链接进来,就会触发newConnection信号,我们只需要实现槽函数

4. mSocket = mServer->nextPendingConnection();//获取客户端连接

//连接QTcpSocket的信号槽,以读取新数据

    QObject::connect(mSocket, &QTcpSocket::readyRead, this, &TcpServer::socket_Read_Data);
    QObject::connect(mSocket, &QTcpSocket::disconnected, this, &TcpServer::socket_Disconnected);

5.read和write数据 和客户端一样

 记录下吧,后面用到udp的时候,再写精致点

ps: 链接时不能开翻墙软件,否则链接失败

猜你喜欢

转载自blog.csdn.net/sono_io/article/details/124104685