QT任务003:实现TCP连接之客户端编写——基于network, QTcpSocket类网络套接字

一  任务描述

1.界面要求 :

一个 网址输入框,一个端口输入框,一个发送信息输入框
一个连接按钮,一个断开连接按钮(或者和连接做成一个按钮),一个发送按钮

2.功能要求:实现tcp链接

(1)连接指定的服务器地址及端口

(2)能发送+接收信息并显示

二  实现过程

前提:   使用QT的网络套接字 需要.pro文件中加入一句:        QT       += network

Ⅰ.客户端不需要监测,比服务器端简单  ,5大步

(1)创建QTcpSocket套接字对象        socket = new QTcpSocket();
(2)使用这个对象连接服务器              socket->connectToHost(IP, port);
(3)使用write函数向服务器发送数据   socket->write(data);
(4)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
 
void MainWindow::socket_Read_Data()
{
    QByteArray buffer;
    //读取缓冲区数据
    buffer = socket->readAll();
}
(5)断开与服务器的连接(关于close()和disconnectFromHost()的区别,可以按F1看帮助)

socket->disconnectFromHost();

Ⅱ 代码实现

1..pro文件

+ _network库

QT       += network # 实现TCP连接

2.UI界面 绘制

PS1:注意写功能前  就改名字!!巧妙使用布局

PS2:先操作  按钮的go to slot (建立一个框架)

3..h文件书写 

+ _读数据,断开连接  2个函数  

+ _套接字socket 的定义

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QTcpSocket>
#include<QtNetwork>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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


private slots:
    void on_pushButton_Connect_clicked();

    void on_pushButton_Send_clicked();


    void socket_Read_Data();   //自己写 读数据
    void socket_Disconnected();//自己写 断开连接

private:
    Ui::MainWindow *ui;

    QTcpSocket *socket;//定义 套接字对象 PS:还没实例化
};

#endif // MAINWINDOW_H

4.mainwindow.cpp文件

(1) + _头文件  #include<QDebug>   #include<QtNetwork>

(2)构造函数

  + _套接字实例化

  + _socket 信号与 槽连接

  +  _界面默认IP 和 端口

  + _发送按钮 未连接不可操作

(3)+ _删除时 释放socket

(4) 连接按钮 槽函数

  + _判断按钮文字是”连接“ -> 获取IP和Port

        + _abort取消现有连接后,连接服务器connectToHost

        + _判断是否连接,通过  waitForConnected()

                      PS:只有用waitForConnected()后,QTcpSocket才真正尝试连接服务器,并返回是否连接的结果。

        +_连接成败结果打印出来,通过qDebug()打印

  +_判断按钮文字不是连接(也就是”断开连接“)

        +_socket断开连接,并更新按钮文字为“连接”

        +_发送按钮 可以使能

(5)发送按钮的槽函数

  +_ 获取文本内容

  +_   以ASCII码发送,通过write() 文本的.toLatin1(),

  +_ flush从缓存区 写到 网络套接字

(6)读取缓存区数据  函数基于 QByteArray类字节数组类

  +_ 定义QByteArray类,并readAll

  +_ 读取的内容 添加到 文本

  +_ 文本区 setText () 进行刷新显示

(7)断开连接函数

  +_ 发送按钮不可用

  +_ 更新按钮的文字为“连接”

  +_ 打印提示信息

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include<QDebug>
#include<QtNetwork>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);//勿忘实例化,在connect之前 所有对象要存在
//连接信号与槽
    //connect(socket,&QTcpSocket::readyRead,this,&MainWindow::socket_Read_Data);
    //connect(socket,&QTcpSocket::disconnected,this,&MainWindow::socket_Disconnected);
    connect(socket,SIGNAL(readyRead()),this,SLOT(socket_Read_Data()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(socket_Disconnected()));

    ui->lineEdit_IP->setText("127.0.0.1");
    ui->lineEdit_Port->setText("6000");
    ui->pushButton_Send->setEnabled(false);//发送按钮先禁止操作
}

MainWindow::~MainWindow()
{
    //增加释放
    delete this->socket;

    delete ui;
}

void MainWindow::on_pushButton_Connect_clicked()//建立TCP 连接
{
    if(ui->pushButton_Connect->text() == tr("连接"))
    {
        QString IP;
        int port;

        IP = ui->lineEdit_IP->text();           //获取IP地址
        port = ui->lineEdit_Port->text().toInt();//获取端口号
        socket->abort();//取消已经有的连接
        socket->connectToHost(IP,port);//连接服务器

        if(!socket->waitForConnected(30000))
        {
            qDebug() << "connection failed!";
            return;
        }
        qDebug() <<"connection successfully!";

        ui->pushButton_Send->setEnabled(true);//发送按钮 使能
        ui->pushButton_Connect->setText("断开连接");//智能检测 变化
    }
    else
    {
        socket->disconnectFromHost();//断开 连接  区别close()  abort()


        ui->pushButton_Connect->setText("连接");


        ui->pushButton_Send->setEnabled(false);//

    }
}

void MainWindow::on_pushButton_Send_clicked()
{
    qDebug() <<"Send: " <<ui->textEdit_3->toPlainText();//获得文本内容
    socket->write(ui->textEdit_3->toPlainText().toLatin1());//内容已ASCII码发送
    socket->flush();//将数据从内部写缓冲区写到底层的网络套接字,而不会造成阻塞。
}


void MainWindow::socket_Read_Data()
{
    QByteArray buffer;
    //读取缓冲区数据
    buffer = socket->readAll();
    if(!buffer.isEmpty())
    {
        QString str = ui->textEdit_Recv->toPlainText();
        str+=tr(buffer);
        //刷新显示
        ui->textEdit_Recv->setText(str);
    }
}

void MainWindow::socket_Disconnected()
{
    //发送按键失能
    ui->pushButton_Send->setEnabled(false);
    //修改按键文字
    ui->pushButton_Connect->setText("连接");
    qDebug() << "Disconnected!";
}

TCP通信原理参考https://blog.csdn.net/u014695839/article/details/70041771

socket 的介绍 https://blog.csdn.net/qq_37002901/article/details/86636813

  


 

发布了102 篇原创文章 · 获赞 3 · 访问量 6709

猜你喜欢

转载自blog.csdn.net/qq_37631516/article/details/104938115