Qt 实现简单的tcp网络通信


背景:
最近计网要结课了,匆忙之间有个计网实验还没做。
上网这里查查那里查查,随便搞搞
然后在 这篇文章里找到了能够实现的代码
自己想着把它图形化一下,最后在超级棒棒糖的帮助下实现了。

成品效果图:

在这里插入图片描述

代码:

工具头文件tool.h

该头文件用于添加一些要用到的库,直接引用这个库,比较方便美观

#ifndef TOOL_H
#define TOOL_H
#include<winsock2.h>
#include<QDateTime>

#include <ws2tcpip.h>
#include <stdio.h>
#include <QDebug>

#include <QNetworkInterface>
#include <QNetworkInterface>
#include <QDebug>
#include <QtNetwork>


#endif // TOOL_H

UI文件代码 ui_widget.h:

/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.12.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QTextBrowser>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QTextBrowser *SeverState;
    QFrame *line;
    QToolButton *send;
    QFrame *line_2;
    QTextBrowser *talk;
    QWidget *horizontalLayoutWidget;
    QHBoxLayout *horizontalLayout;
    QLabel *label_2;
    QLineEdit *posline;
    QToolButton *Open;
    QGroupBox *groupBox;
    QLabel *label_3;
    QLineEdit *TheIp;
    QLabel *label_4;
    QLineEdit *TheHost;
    QToolButton *connectIp;
    QTextBrowser *Showip;
    QLabel *label_5;
    QTextBrowser *connectState;
    QTextEdit *TextCin;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QString::fromUtf8("Widget"));
        Widget->resize(1106, 823);
        label = new QLabel(Widget);
        label->setObjectName(QString::fromUtf8("label"));
        label->setGeometry(QRect(20, 180, 131, 41));
        label->setStyleSheet(QString::fromUtf8("font:20px"));
        SeverState = new QTextBrowser(Widget);
        SeverState->setObjectName(QString::fromUtf8("SeverState"));
        SeverState->setGeometry(QRect(10, 240, 271, 131));
        line = new QFrame(Widget);
        line->setObjectName(QString::fromUtf8("line"));
        line->setGeometry(QRect(350, 610, 761, 21));
        line->setFrameShape(QFrame::HLine);
        line->setFrameShadow(QFrame::Sunken);
        send = new QToolButton(Widget);
        send->setObjectName(QString::fromUtf8("send"));
        send->setGeometry(QRect(940, 720, 151, 71));
        send->setStyleSheet(QString::fromUtf8("font:30px"));
        line_2 = new QFrame(Widget);
        line_2->setObjectName(QString::fromUtf8("line_2"));
        line_2->setGeometry(QRect(340, 0, 31, 821));
        line_2->setFrameShape(QFrame::VLine);
        line_2->setFrameShadow(QFrame::Sunken);
        talk = new QTextBrowser(Widget);
        talk->setObjectName(QString::fromUtf8("talk"));
        talk->setGeometry(QRect(370, 20, 721, 571));
        horizontalLayoutWidget = new QWidget(Widget);
        horizontalLayoutWidget->setObjectName(QString::fromUtf8("horizontalLayoutWidget"));
        horizontalLayoutWidget->setGeometry(QRect(0, 80, 351, 71));
        horizontalLayout = new QHBoxLayout(horizontalLayoutWidget);
        horizontalLayout->setSpacing(6);
        horizontalLayout->setContentsMargins(11, 11, 11, 11);
        horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
        horizontalLayout->setContentsMargins(0, 0, 0, 0);
        label_2 = new QLabel(horizontalLayoutWidget);
        label_2->setObjectName(QString::fromUtf8("label_2"));
        label_2->setStyleSheet(QString::fromUtf8("font:25px;"));

        horizontalLayout->addWidget(label_2);

        posline = new QLineEdit(horizontalLayoutWidget);
        posline->setObjectName(QString::fromUtf8("posline"));

        horizontalLayout->addWidget(posline);

        Open = new QToolButton(horizontalLayoutWidget);
        Open->setObjectName(QString::fromUtf8("Open"));
        Open->setStyleSheet(QString::fromUtf8("font:30px"));

        horizontalLayout->addWidget(Open);

        groupBox = new QGroupBox(Widget);
        groupBox->setObjectName(QString::fromUtf8("groupBox"));
        groupBox->setGeometry(QRect(10, 390, 301, 261));
        groupBox->setStyleSheet(QString::fromUtf8("font:20px"));
        label_3 = new QLabel(groupBox);
        label_3->setObjectName(QString::fromUtf8("label_3"));
        label_3->setGeometry(QRect(10, 30, 221, 31));
        TheIp = new QLineEdit(groupBox);
        TheIp->setObjectName(QString::fromUtf8("TheIp"));
        TheIp->setGeometry(QRect(10, 60, 281, 31));
        label_4 = new QLabel(groupBox);
        label_4->setObjectName(QString::fromUtf8("label_4"));
        label_4->setGeometry(QRect(10, 110, 151, 41));
        TheHost = new QLineEdit(groupBox);
        TheHost->setObjectName(QString::fromUtf8("TheHost"));
        TheHost->setGeometry(QRect(10, 160, 281, 31));
        connectIp = new QToolButton(groupBox);
        connectIp->setObjectName(QString::fromUtf8("connectIp"));
        connectIp->setGeometry(QRect(20, 210, 161, 41));
        Showip = new QTextBrowser(Widget);
        Showip->setObjectName(QString::fromUtf8("Showip"));
        Showip->setGeometry(QRect(115, 10, 231, 41));
        label_5 = new QLabel(Widget);
        label_5->setObjectName(QString::fromUtf8("label_5"));
        label_5->setGeometry(QRect(10, 10, 101, 41));
        label_5->setStyleSheet(QString::fromUtf8("font:25px"));
        connectState = new QTextBrowser(Widget);
        connectState->setObjectName(QString::fromUtf8("connectState"));
        connectState->setGeometry(QRect(30, 660, 256, 151));
        TextCin = new QTextEdit(Widget);
        TextCin->setObjectName(QString::fromUtf8("TextCin"));
        TextCin->setGeometry(QRect(360, 620, 561, 191));

        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QApplication::translate("Widget", "\345\260\217chat", nullptr));
        label->setText(QApplication::translate("Widget", "\346\234\215\345\212\241\347\253\257\347\212\266\346\200\201\357\274\232", nullptr));
        send->setText(QApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));
        label_2->setText(QApplication::translate("Widget", "\346\234\215\345\212\241\345\231\250\345\274\200\346\224\276\347\253\257\345\217\243", nullptr));
        Open->setText(QApplication::translate("Widget", "\346\211\223\345\274\200", nullptr));
        groupBox->setTitle(QApplication::translate("Widget", "\350\277\236\346\216\245\345\214\272", nullptr));
        label_3->setText(QApplication::translate("Widget", "\345\257\271\346\226\271\346\234\215\345\212\241\345\231\250ip\357\274\232", nullptr));
        label_4->setText(QApplication::translate("Widget", "\345\257\271\346\226\271\346\234\215\345\212\241\347\253\257\345\217\243\357\274\232", nullptr));
        connectIp->setText(QApplication::translate("Widget", "\350\277\236\346\216\245", nullptr));
        label_5->setText(QApplication::translate("Widget", "\346\234\254\346\234\272ip:", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

窗口头文件 widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "tool.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);

    ~Widget();

private:
    Ui::Widget *ui;
    QTcpServer server;     //TCP控制本地服务器
    quint16 host;           //开放端口
    QTcpSocket *socket = new QTcpSocket(this);     //连接其他的Socket
    QTcpSocket *so = new QTcpSocket(this);         //被连接的Socket
    QString AimIp;
    quint16 AimPort;


private slots:
    void openHost(); //开放某个端口
    void toConnect(); //连接端口
    void toSend();      //发送信息
};

#endif // WIDGET_H

窗口源文件widget.cpp:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for(int nIter=0; nIter<list.count(); nIter++)
    {
        if(!list[nIter].isLoopback())
        {
            if(list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
            {
                qDebug() << list[nIter].toString();
                ui->Showip->append(list[nIter].toString());
            }
        }
    }

    connect(ui->Open, &QToolButton::clicked,this, &Widget::openHost);//打开端口
    connect(ui->connectIp, &QToolButton::clicked,this,&Widget::toConnect);//连接
    connect(ui->send, &QToolButton::clicked, this,&Widget::toSend);
    //被连接
    connect(&server, &QTcpServer::newConnection, this, [=]() {
        so = server.nextPendingConnection();
        QString ip = so->peerAddress().toString();
        quint16 port = so->peerPort();
        qDebug() << "New connection from " << ip << ":" << port;

        QString m = "<font color='blue'>有新的连接来自"+ip+":"+QString::number(port)+"</font>";
        ui->SeverState->append(m);
        //被连接后接收信息:
        connect(so, &QTcpSocket::readyRead, this, [=]() {
            QDateTime currentDateTime = QDateTime::currentDateTime();
            QString ip = so->peerAddress().toString();
            QByteArray data = so->readAll();
            qDebug() << "Received data:" << data;
            QString mag1 = QString::fromUtf8(data);
            qDebug()<<currentDateTime;
            QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
            QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+mag1+"</font>";
            ui->talk->append(mag);
        });
    });


    //连接成功:
    connect(socket, &QTcpSocket::connected, this, [=]() {
        qDebug() << "Connected to server.";

        // 发送信息给服务端
        QByteArray message = "连接你了";
        socket->write(message);
    });

    // 接收服务端发送的信息
    connect(socket, &QTcpSocket::readyRead, this, [=]() {
        QDateTime currentDateTime = QDateTime::currentDateTime();
        QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
        QString ip = socket->peerAddress().toString();
        QByteArray data = socket->readAll();
        QString message = QString::fromUtf8(data);
        qDebug() << "Received message from server:" << message;
        QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+message+"</font>";
        ui->talk->append(mag);
    });


}



void Widget::openHost(){
    int temp = this->ui->posline->text().toInt();
    this->host = static_cast<quint16>(temp);
    qDebug()<<"端口:"<<this->host<<endl;

    server.close();
    if(!this->server.listen(QHostAddress::Any, this->host)){
        qDebug()<<"端口开放失败"<<endl;
        this->ui->SeverState->append("<font color='red'>端口开放失败</font>");
    }
    else{
        this->ui->SeverState->append(this->ui->posline->text()+"端口已开放");
    }

}

void Widget::toConnect(){

    AimIp = ui->TheIp->text();
    int h = ui->TheHost->text().toInt();
    AimPort = static_cast<quint16>(h);
    socket->connectToHost(AimIp,AimPort);
    if (socket->waitForConnected()) {
        // 连接成功
        qDebug() << "Connected to server!";
        QString mag = "连接"+this->AimIp+"的端口"+ui->TheHost->text()+"成功";
        ui->connectState->append(mag);



    } else {
        // 连接失败
        QString mag = "连接"+this->AimIp+"的端口"+ui->TheHost->text()+"失败";
        qDebug() << "Failed to connect to server: " << socket->errorString();
        mag = "<font color='red'>"+mag+"</font>";
        ui->connectState->append(mag);
    }
}

void Widget::toSend(){
    QString mag = this->ui->TextCin->toPlainText();
    so->write(mag.toUtf8());
    so->flush();
    so->waitForBytesWritten();
    socket->write(mag.toUtf8());
    socket->flush();
    socket->waitForBytesWritten();
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
    QString smag = strDateTime+"向"+this->AimIp+"发送消息:"+mag;
    ui->talk->append(smag);
    ui->TextCin->clear();
}


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

相关代码说明:

Qt获取本机ip:

	QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for(int nIter=0; nIter<list.count(); nIter++)
    {
        if(!list[nIter].isLoopback())
        {
            if(list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
            {
                qDebug() << list[nIter].toString();//输出端口信息
            }
        }
    }
    

Qt 打开,监视服务端端口:

QTcpServer server;
quint16 host = 8080;
server.listen(QHostAddress::Any, host);

这里的listen()函数则是打开端口并监视,不过要注意,一个server只能打开监视一个端口。

Qt 客户端连接服务端:

这里的客户端其实也就是你自己的主机,你自己的主机也可以充当服务端捏。

	QString AimIp = "127.0.0.1"
    quint16 AimPort = 8080;
    QTcpSocket *socket = new QTcpSocket();
    socket->connectToHost(AimIp,AimPort);//连接函数
    if (socket->waitForConnected()) {
        // 连接成功
        qDebug() << "Connected to server!";

    } else {
        // 连接失败
        qDebug() << "连接失败";
    }

Qt 服务端被连接后接收显示并接收消息:

connect(&server, &QTcpServer::newConnection, this, [=]() {
        so = server.nextPendingConnection();
        QString ip = so->peerAddress().toString();
        quint16 port = so->peerPort();
        qDebug() << "New connection from " << ip << ":" << port;

        QString m = "<font color='blue'>有新的连接来自"+ip+":"+QString::number(port)+"</font>";
        ui->SeverState->append(m);
        //被连接后接收信息:
        connect(so, &QTcpSocket::readyRead, this, [=]() {
            QDateTime currentDateTime = QDateTime::currentDateTime();
            QString ip = so->peerAddress().toString();
            QByteArray data = so->readAll();//获取消息
            qDebug() << "Received data:" << data;
            QString mag1 = QString::fromUtf8(data);
            qDebug()<<currentDateTime;
            QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
            QString mag = "<font color='blue'>"+strDateTime+"收到来自"+ip+"的消息:"+mag1+"</font>";
            ui->talk->append(mag);
        });
    });

Qt 发送消息:

主要通过QTcpSocket的write()函数进行发送消息。

void Widget::toSend(){
    QString mag = this->ui->TextCin->toPlainText();
    so->write(mag.toUtf8());
    so->flush();
    so->waitForBytesWritten();
    socket->write(mag.toUtf8());
    socket->flush();
    socket->waitForBytesWritten();
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString strDateTime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
    QString smag = strDateTime+"向"+this->AimIp+"发送消息:"+mag;
    ui->talk->append(smag);
    ui->TextCin->clear();
}

最后:

这个东东只能进行简单的tcp通讯,而且要求连接的是同一局域网的两台设备才能进行交流,不过也的确是这样的,除非你有额外的设备什么的~
当然,如果你想整个QQ那种的东西出来的话,可以整个中间服务器,然后让不同的客户端都访问那个中间服务器,通过中间服务器进行交流~

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泉绮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值