QT实现基于TCP的网络通信

写在前面

基于TCP(传输控制协议)通信的原理涉及到两个主要角色:服务器和客户端。以下是基于TCP通信的简要原理:

  • 服务器端: 服务器端首先创建一个QTcpServer对象,该对象负责监听指定的IP地址和端口,等待客户端的连接请求。 当有客户端连接请求到达时,服务器端会创建一个新的QTcpSocket对象,用于与该客户端建立通信通道。 通过QTcpSocket对象,服务器端和客户端可以进行双向的数据传输。
  • 客户端: 客户端创建一个QTcpSocket对象,用于连接到服务器的指定IP地址和端口。 一旦连接建立,客户端可以通过该QTcpSocket对象向服务器端发送数据,并接收服务器端的响应数据。 客户端也可以监听来自服务器的数据,以实现双向通信。
  • 数据传输: 数据在传输过程中会被拆分成小的数据包,每个数据包包含一部分信息。 TCP负责确保数据的可靠传输,通过序列号、确认应答、超时重传等机制来保证数据的完整性和顺序性。 在服务器和客户端之间建立的TCP连接是全双工的,允许双方同时进行读写操作。
  • 连接的建立和断开: 在TCP通信中,连接的建立使用三次握手的过程,确保双方都能够正确收到对方的连接请求和确认。 连接的断开使用四次挥手的过程,确保双方都能够正确关闭连接。

服务器界面:

服务器代码:

#include "serverwindow.h"
#include "ui_serverwindow.h"

#include <QTime>

ServerWindow::ServerWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ServerWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("TCP服务器");

    QLabel *label =new QLabel("连接状态:未连接");
    this->ui->statusbar->addWidget(label);
    //设置一个默认端口
    this->ui->portlineEdit->setText("8088");
    m_server = new QTcpServer(this); //初始化监听的服务器对象

    //当服务器接收到新的连接时,获取新连接的套接字对象,接着使用QTcpSocket对象与客户端进行通信
    connect(m_server, &QTcpServer::newConnection, this, [=](){
        m_socket = m_server->nextPendingConnection();
            qDebug()<<m_socket;
        label->setText("连接状态:已连接");
        //接收客户段信息
        connect(m_socket, &QTcpSocket::readyRead, this, [=](){
            QByteArray data= m_socket->readAll();
            this->ui->recordTextEdit->append("客户端("+QTime::currentTime().toString()+"):"+data);
        });
        connect(m_socket, &QTcpSocket::disconnected, this, [=](){
            m_socket->close();
            delete m_socket;
            label->setText("连接状态:未连接");
        });
    });

}

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

void ServerWindow::on_listenBtn_clicked()
{
     //获取端口号
    unsigned short port = this->ui->portlineEdit->text().toUShort();
    //启动监听,将服务器绑定到本地的任意IP地址和指定的端口上。
    this->m_server->listen(QHostAddress::Any, port);
    this->ui->listenBtn->setDisabled(true);

}


void ServerWindow::on_sendMsgBtn_clicked()
{

    QString msg = this->ui->msgTextEdit->toPlainText();
    //将字节数组发送给服务器
    this->m_socket->write(msg.toUtf8());
    this->ui->recordTextEdit->append("服务器("+QTime::currentTime().toString()+"):"+msg);
    this->ui->msgTextEdit->clear();
}

客户端界面:

客户端代码:


#include "clientwindow.h"
#include "ui_clientwindow.h"
#include <QHostAddress>
#include <QTime>
ClientWindow::ClientWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ClientWindow)
{
    ui->setupUi(this);
    setWindowTitle("客户端");
    QLabel *label =new QLabel("连接状态:未连接");
    this->ui->statusbar->addWidget(label);


    this->ui->portlineEdit->setText("8088"); //与服务器端口保持一致
    this->ui->IPlineEdit->setText("127.0.0.1"); //本地ip
    this->m_socket = new QTcpSocket(this); //初始化套接字对象

    connect(m_socket, &QTcpSocket::readyRead, this, [=](){
        QByteArray data = m_socket->readAll();
        this->ui->recordTextEdit->append("服务器("+QTime::currentTime().toString()+"):"+data);
    });
    connect(m_socket, &QTcpSocket::disconnected, this, [=](){
        this->m_socket->close();
        //this->m_socket->deleteLater();
        label->setText("连接状态:未连接");
        this->ui->recordTextEdit->append("断开连接...");
    });
    connect(m_socket, &QTcpSocket::connected, this, [=](){
        label->setText("连接状态:已连接");
        this->ui->recordTextEdit->append("连接成功...");
    });
}

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



void ClientWindow::on_ConnectBtn_clicked()
{
    QString ip = this->ui->IPlineEdit->text();
    unsigned short port = this->ui->portlineEdit->text().toUShort();
    //连接到指定的主机和端口
    m_socket->connectToHost(QHostAddress(ip),port);
}


void ClientWindow::on_sendMsgBtn_clicked()
{
    QString msg = this->ui->SenMsgTextEdit->toPlainText();
    m_socket->write(msg.toUtf8());
    this->ui->recordTextEdit->append("客户端("+QTime::currentTime().toString()+"):"+msg);
    this->ui->SenMsgTextEdit->clear();
}


void ClientWindow::on_DisConnectBtn_clicked()
{
    this->m_socket->close();
}

实现:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT中,可以使用QTcpSocket和QTcpServer类来实现基于TCP网络通信,其中QTcpSocket用于客户端,QTcpServer用于服务器端。 服务器端实现步骤: 1. 创建一个QTcpServer对象,并监听指定的IP地址和端口号。 2. 监听到新的连接时,创建一个QTcpSocket对象,并将其与客户端进行连接。 3. 通过QTcpSocket对象进行数据的发送和接收。 客户端实现步骤: 1. 创建一个QTcpSocket对象。 2. 使用QTcpSocket对象与服务器端进行连接。 3. 通过QTcpSocket对象进行数据的发送和接收。 下面是一个简单的示例代码,展示了服务器端和客户端的实现: 服务器端代码: ```cpp QTcpServer server; server.listen(QHostAddress::Any, 1234); // 监听IP地址和端口号 connect(&server, &QTcpServer::newConnection, [&server]() { QTcpSocket* clientSocket = server.nextPendingConnection(); connect(clientSocket, &QTcpSocket::readyRead, [clientSocket]() { QByteArray data = clientSocket->readAll(); // 处理接收到的数据 qDebug() << "Received data from client: " << data; }); }); ``` 客户端代码: ```cpp QTcpSocket socket; socket.connectToHost("127.0.0.1", 1234); // 连接到服务器的IP地址和端口号 if (socket.waitForConnected()) { socket.write("Hello server"); // 发送数据到服务器 socket.waitForBytesWritten(); } ``` 以上代码只是一个简单的示例,实际应用中可能需要处理更复杂的数据交互和错误处理。需要注意的是,QTcpSocket和QTcpServer类都继承自QObject类,因此可以使用信号与槽机制来处理连接、数据接收等事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值