【qt】 TCP编程小项目

话不多说,先一睹芳颜

项目目录

一.服务端

1.界面设计

2.服务端获取主机地址

将主机地址放在了一个容器中.

3.初始化服务端

当有新的客户端请求连接时,会发出newConnection()的信号.

4.服务端开启监听

注意listen函数的参数类型,要转换一下.

5.套接字socket

当有客户端请求连接后,我们需要套接字来作为服务端和客户端的接口.

6.服务端的读写

当有信息可以读的时候,我们就可以来读信息.

发送信息用write ,注意要用utf8编码.

7.socket的其他信号的槽函数

8.服务端关闭监听

9.完整代码

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostInfo>
#include <QHostAddress>
#include <QLabel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButtonOpen_clicked();

    void on_pushButtonClose_clicked();

    void onNewConnection();

    void onReadyRead();

    void onConnected();

    void onDisconnected();

    void onStateChanged(QAbstractSocket::SocketState socketState);

private:
    Ui::MainWindow *ui;

    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
    QStringList addrs;
    QLabel *labelState;


    void initTCPServer();
    void getHostAddress();
    void sendMsg(const QString&str);
    void initLabel();
};
#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

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

    initTCPServer();
    initLabel();

}

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


void MainWindow::on_pushButtonOpen_clicked()
{
    getHostAddress();
    int i=rand()%addrs.count();
    QString addr=addrs.at(i);
    ui->labelIP->setText("服务器地址:"+addr);
    quint16 port=rand()%9000+8000;
    ui->labelPort->setText("服务器端口:"+QString::number(port));
    QHostAddress IP(addr);
    tcpServer->listen(IP,port);

    ui->pushButtonOpen->setEnabled(false);
    ui->pushButtonClose->setEnabled(true);
    ui->labelIP->show();
    ui->labelPort->show();
}

void MainWindow::on_pushButtonClose_clicked()
{
    if(tcpServer->isListening())
    {
        tcpServer->close();
        ui->pushButtonOpen->setEnabled(true);
        ui->pushButtonClose->setEnabled(false);
        ui->labelIP->hide();
        ui->labelPort->hide();
    }
}

void MainWindow::onNewConnection()
{
    tcpSocket=tcpServer->nextPendingConnection();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState socketState)),
            this,SLOT(onStateChanged(QAbstractSocket::SocketState)));
    onStateChanged(tcpSocket->state());
}


void MainWindow::onReadyRead()
{
    QString str;
    while(tcpSocket->canReadLine())
    {
        QString read=tcpSocket->readLine();
        //qDebug()<<tcpSocket->readLine()<<endl;
        if(read=="人有悲欢离合\n")
        {
            str="月有阴晴圆缺";
            sendMsg(str);
        }
        else if(read=="此情可待成追忆\n")
        {
            str="只是当时已惘然";
            sendMsg(str);
        }
        else if(read=="宁教我负天下人\n")
        {
            str="休教天下人负我";
            sendMsg(str);
        }
        else
        {
            str="喂喂喂!你在说啥?";
            sendMsg(str);
        }
    }
}

void MainWindow::onConnected()
{
    labelState->setText("连接状态: 已连接");
}

void MainWindow::onDisconnected()
{
    labelState->setText("连接状态: 已断开连接");
    tcpSocket->deleteLater();//之后删
}

void MainWindow::onStateChanged(QAbstractSocket::SocketState socketState)
{
    switch (socketState) {
    case QAbstractSocket::UnconnectedState:
        labelState->setText("连接状态: 已断开连接");
        break;
    case QAbstractSocket::ConnectedState:
        labelState->setText("连接状态: 已连接");
        break;
    }
}

void MainWindow::initTCPServer()
{
    tcpServer=new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}

void MainWindow::getHostAddress()
{
    QHostInfo hostInfo =QHostInfo::fromName(QHostInfo::localHostName());
    QList<QHostAddress> lists=hostInfo.addresses();
    for(int i=0;i<lists.count();i++)
    {
        QHostAddress address=lists[i];
        if(address.protocol()==QAbstractSocket::IPv4Protocol)
        {
            addrs.append(address.toString());
        }
    }
}

void MainWindow::sendMsg(const QString &str)
{
    QByteArray msg= str.toUtf8();
    msg.append('\n');
    tcpSocket->write(msg);
}

void MainWindow::initLabel()
{
    labelState=new QLabel("连接状态: 未连接");
    ui->statusbar->addWidget(labelState);
    ui->labelIP->hide();
    ui->labelPort->hide();

    QLinearGradient gradient(0,0,ui->label->width(),ui->label->height());
    gradient.setColorAt(0,Qt::green);
    gradient.setColorAt(1,Qt::blue);

    QPalette palette;
    palette.setBrush(QPalette::WindowText,QBrush(gradient));
    ui->label->setPalette(palette);
}

二.客户端

1.界面设计

2.套接字的初始化

3.连接服务器

如果连接成功,就弹出我们的发送框.

这里的tcpSocketGet是在对话框中获取到套接字的,然后可以来发送信息.

4.界面设计师类


5.客户端的读写

读到的信息添加到对话框中.

发送信息:

发送的信息都添加了一个换行符,因为这样可以判断一行,然后对方进行读取.

6.客户端关闭连接

7.完整代码

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>
#include <QLabel>
#include <dialog.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButtonConnect_clicked();

    void on_pushButtonDisConnect_clicked();

    void onConnected();

    void onDisconnected();

    void onReadyRead();

private:
    Ui::MainWindow *ui;

    QTcpSocket*tcpSocket;

    QLabel* labState;
    QLabel* labIP;
    QLabel* labPort;
    Dialog* chat;


    void initTCPSocket();
    void intitLabel();
};
#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    initTCPSocket();
    intitLabel();
}

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

void MainWindow::initTCPSocket()
{
    tcpSocket=new QTcpSocket(this);
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onReadyRead()));

}

void MainWindow::intitLabel()
{
    labState=new QLabel(this);
    labState->setMinimumWidth(100);
    labPort=new QLabel(this);
    labPort->setMinimumWidth(100);
    labIP=new QLabel(this);
    this->statusBar()->addWidget(labState);
    this->statusBar()->addWidget(labPort);
    this->statusBar()->addWidget(labIP);
}


void MainWindow::on_pushButtonConnect_clicked()
{
    QString addr=ui->lineEditAddr->text();
    QString port=ui->lineEditProt->text();
    if(addr==NULL||port==NULL)return;
    QHostAddress IP(addr);
    tcpSocket->connectToHost(IP,port.toInt());
}

void MainWindow::on_pushButtonDisConnect_clicked()
{
    if(tcpSocket->state()==QAbstractSocket::ConnectedState)
    {
        tcpSocket->disconnectFromHost();
        chat->close();
    }
}

void MainWindow::onConnected()
{
    labState->setText("连接状态: 已连接");
    labPort->setText("服务器端口: "+QString::number(tcpSocket->peerPort()));
    labIP->setText("服务器IP: "+tcpSocket->peerAddress().toString());
    chat=new Dialog(this);
    //this->hide();
    chat->tcpSocketGet(tcpSocket);
    chat->show();
}

void MainWindow::onDisconnected()
{
    labState->setText("连接状态: 已断开连接");
    labState->clear();
    labIP->clear();
    labPort->clear();
}


void MainWindow::onReadyRead()
{
    while(tcpSocket->canReadLine())
    {
        QString str=tcpSocket->readLine();
        chat->setMsg(str);
    }
}

dialog.h

cpp 复制代码
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QTcpSocket>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = nullptr);
    ~Dialog();

    void setMsg(const QString&str);
    void tcpSocketGet(QTcpSocket *tcpSocket);

private slots:
    void on_pushButton_clicked();

private:
    Ui::Dialog *ui;
    QTcpSocket*tcpSocket;


protected:
    void closeEvent(QCloseEvent*event);

};

#endif // DIALOG_H

dialog.cpp

cpp 复制代码
#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QHostAddress>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    ui->plainTextEdit->setReadOnly(true);
}

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

void Dialog::setMsg(const QString &str)
{
    ui->plainTextEdit->appendPlainText("服务器: "+str);
}

void Dialog::tcpSocketGet(QTcpSocket *tcpSocket)
{
    this->tcpSocket=tcpSocket;
    //qDebug()<<this->tcpSocket->peerAddress();
}

void Dialog::on_pushButton_clicked()
{
    QString str=ui->lineEdit->text();
    QByteArray msg=str.toUtf8();
    msg.append('\n');
    tcpSocket->write(msg);
    ui->plainTextEdit->appendPlainText("客户: "+str);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();
}

void Dialog::closeEvent(QCloseEvent *event)
{
    if(tcpSocket->state()==QAbstractSocket::ConnectedState)
    {
        tcpSocket->disconnectFromHost();
    }

    event->accept();
}

三.结语

当然我这里只是稍微的演示一下,你也可以自己在服务端做手脚,自己发送信息也可以.

念头通达,现在应该算是炼气期1层.

相关推荐
Dream_Snowar7 分钟前
速通Python 第三节
开发语言·python
唐诺17 分钟前
几种广泛使用的 C++ 编译器
c++·编译器
南宫生1 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
sanguine__1 小时前
Web APIs学习 (操作DOM BOM)
学习
mahuifa1 小时前
混合开发环境---使用编程AI辅助开发Qt
人工智能·vscode·qt·qtcreator·编程ai
冷眼看人间恩怨1 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
信号处理学渣1 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客1 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin1 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin