Qt 编写 TcpClient 程序 详细步骤

在 Qt 框架中开发 TCP 客户端程序是网络编程的基础应用场景,本文将详细讲解如何从零开始编写一个功能完整的 TCP 客户端,实现与服务端的连接、数据发送和数据接收功能。

一、开发环境准备

  1. 基础环境:确保已安装 Qt 开发环境(推荐 Qt 5.12 及以上版本),包含 Qt Creator 编辑器和对应的编译套件(如 MinGW、MSVC)。
  2. 核心依赖 :Qt 的网络模块(Qt Network)是实现 TCP 通信的核心,需在项目配置中启用该模块。

二、项目创建与配置

1. 创建 Qt Widgets 项目

  • 打开 Qt Creator,选择「New Project」→「Application」→「Qt Widgets Application」,设置项目名称(如TcpClient)和保存路径。
  • 选择基类为QWidget(与示例代码一致),取消「Generate form」外的不必要选项,完成项目创建。

2. 配置项目文件(.pro)

TCP 通信依赖Qt Network模块,需在项目的.pro文件中添加该模块,否则会出现编译错误:

cpp 复制代码
#-------------------------------------------------
#
# Project created by QtCreator 2017-02-12T17:03:25
#
#-------------------------------------------------

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = my_client
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        widget.cpp \
    tcpsocket.cpp

HEADERS  += widget.h \
    tcpsocket.h

FORMS    += widget.ui

三、界面设计(widget.ui)

示例代码中包含按钮、输入框、列表控件,需在 UI 设计器中完成以下布局:

  1. 控件添加
    • 按钮 1(pushButton):用于连接服务端,文本设置为「连接服务器」。
    • 按钮 2(pushButton_2):用于发送数据,文本设置为「发送」。
    • 行编辑框(lineEdit):用于输入要发送的文本内容。
    • 列表控件(listWidget):用于显示接收到的服务端数据。
  2. 布局调整
    • 可使用垂直布局 / 水平布局组合控件,确保界面美观且自适应窗口大小。

四、核心代码实现

1. 头文件声明(widget.h)

需声明自定义 TCP 套接字对象、槽函数(连接、发送、接收数据):

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}
class tcpsocket;
class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();
    void readData();
    void on_pushButton_2_clicked();

private:
    tcpsocket *socket;
    Ui::Widget *ui;
};

#endif // WIDGET_H

2. 源文件实现(widget.cpp)

(1)构造函数初始化

设置窗口标题,初始化 UI:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
// 若使用自定义tcpsocket,包含对应头文件:#include "tcpsocket.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("客户端");  // 设置窗口标题
    socket = nullptr;  // 初始化套接字对象,避免野指针
}

Widget::~Widget()
{
    delete ui;
    // 析构时关闭套接字连接
    if(socket != nullptr)
    {
        socket->disconnectFromHost();
        socket->deleteLater();
    }
}
(2)连接服务器功能

点击「连接服务器」按钮时,创建套接字对象并连接指定 IP 和端口:

cpp 复制代码
void Widget::on_pushButton_clicked()
{
    ui->pushButton->setEnabled(false);
    QString ipAddress="192.168.10.2";
    socket=new tcpsocket(this);
    socket->connectToHost(ipAddress,8010);
    connect(socket,SIGNAL(readyRead()),this,SLOT(readData()));

    // 关联连接成功/失败信号,增加反馈
       connect(socket, &QTcpSocket::connected, [=](){
           ui->listWidget->addItem("成功连接到服务器!");
       });
       connect(socket, &QTcpSocket::disconnected, [=](){
           ui->listWidget->addItem("与服务器断开连接!");
           ui->pushButton->setEnabled(true);  // 重新启用连接按钮
       });
}
(3)接收服务端数据

当套接字有可读数据时,读取并显示到列表控件:

cpp 复制代码
void Widget::readData()
{
    // 读取所有接收到的数据
    QByteArray buffer = socket->readAll();
    if(!buffer.isEmpty())
    {
        qDebug() << "接收数据:" << buffer;  // 控制台输出
        ui->listWidget->addItem(buffer);    // 界面显示
    }
}
(4)发送数据到服务端

点击「发送」按钮时,将输入框的文本发送到服务端:

cpp 复制代码
void Widget::on_pushButton_2_clicked()
{
    // 获取输入框文本
    QString str = ui->lineEdit->text();
    if(str.isEmpty())  // 空内容不发送
        return;
    
    // 转换为UTF-8编码的字节数组(兼容中文)
    QByteArray byte = str.toUtf8();
    
    // 发送数据
    socket->write(byte);
    

}

3. 自定义 tcpsocket 类

cpp 复制代码
#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QObject>
#include <QTcpSocket>
class tcpsocket : public QTcpSocket
{
    Q_OBJECT
public:
    tcpsocket(QObject *parent);
};

#endif // TCPSOCKET_H


#include "tcpsocket.h"

tcpsocket::tcpsocket(QObject *parent):QTcpSocket(parent)
{

}
相关推荐
这个DBA有点耶3 分钟前
索引优化深潜(下):索引合并、ICP 与索引设计的实战法则
数据库·mysql·架构
努力努力再努力wz20 分钟前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
J2虾虾27 分钟前
C 语言 void 完全用法
c语言·开发语言
八解毒剂40 分钟前
数据结构-平衡二叉树——对二叉搜索树的优化
数据结构·c++·算法
JdSnE27zv41 分钟前
Qt 操作SQLite数据库
数据库·qt·sqlite
会Tk矩阵群控的小木44 分钟前
基于Python的iMessage短信群发与社媒多账号统一管理系统实现
开发语言·windows·python·新媒体运营·开源软件·个人开发
我是一颗柠檬1 小时前
【Java项目技术亮点】分库分表+数据路由策略:单表5000万后的架构升级方案
java·开发语言·分布式·架构
wu_ye_m1 小时前
学习c语言第35天 函数声明和定义
c语言·开发语言·学习
tedcloud1231 小时前
HyperFrames部署教程:用HTML生成MP4视频
前端·数据库·人工智能·html·音视频
布朗克1681 小时前
25 IO流高级操作——序列化、NIO与Files工具类
java·数据库·io·nio