【qt】 TCP编程小项目

简介: 【qt】 TCP编程小项目

话不多说,先一睹芳颜

一.服务端

1.界面设计

2.服务端获取主机地址

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

3.初始化服务端

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

4.服务端开启监听

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

5.套接字socket

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

6.服务端的读写

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

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

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

8.服务端关闭监听

9.完整代码

mainwindow.h

#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

#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

#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

#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

#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

#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层.

相关文章
|
2月前
|
网络协议
【qt】TCP客户端信息的接受和发送
【qt】TCP客户端信息的接受和发送
33 0
|
2月前
|
网络协议
【qt】TCP客户端如何断开连接?
【qt】TCP客户端如何断开连接?
54 0
|
2月前
|
网络协议
【qt】TCP 服务端怎么收到信息?
【qt】TCP 服务端怎么收到信息?
30 0
|
3月前
|
网络协议
Qt中的网络编程(Tcp和Udp)运用详解以及简单示范案例
Tcp和Udp是我们学习网络编程中经常接触到的两个通讯协议,在Qt也被Qt封装成了自己的库供我们调用,对于需要进行网络交互的项目中无疑是很重要的,希望这篇文章可以帮助到大家。 是关于Qt中TCP和UDP的基本使用和特点:
498 7
|
2月前
【qt】平面CAD(计算机辅助设计 )项目 上
【qt】平面CAD(计算机辅助设计 )项目 上
40 0
|
2月前
【qt】项目移植
【qt】项目移植
24 0
【qt】项目移植
|
2月前
【Qt项目专栏】贪吃蛇小游戏1.0
【Qt项目专栏】贪吃蛇小游戏1.0
78 5
|
2月前
CMake自动打包--Qt项目
CMake自动打包--Qt项目
49 0
|
2月前
|
数据安全/隐私保护
【qt】考试系统项目
【qt】考试系统项目
35 0
关于Qt的pri模块化编程详解
关于Qt的pri模块化编程详解