6、Qt学习笔记--TCP

43人阅读 评论(0) 收藏 举报
分类:

一、TCP简介

1、


二、创建示例工程

1、流程分析

(1)客户端

//
客户端
1、创建QTcpSocket套接字对象
socket = new QTcpSocket();

2、使用这个对象连接服务器
socket->connectToHost(ip, port);

3、使用write函数向服务器发送数据
socket->write(data);

4、当socket接收缓冲区有新数据到来时,会发出readyRead()信号,因此为该信号添加槽函数以读取数据
connect(socket, SIGNAL(readyRead()), this, SLOT(socket_read_data()));

viod Client::socket_read_data()
{
	QByteArray buffer;
	//获取缓冲区数据
	buffer = socket->readAll();
}

5、断开与服务器的连接(注意close() 和 disconnectFromHost() 不同)
socket->disconnectFromHost();
//

(2)服务端

//
服务端
1、创建QTcpServer对象
server = new QTcpServer();

2、侦听一个端口,使得客户端可以使用这个端口访问服务器
server->listen(QHostAddress::Any, port);

3、当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接收客户端访问
connect(server, SIGNAL(newConnection()), this, SLOT(server_new_connnect()));

void Server::server_new_connnect()
{
	//获取客户端连接
	socket = server->nextPendingConnection();
}

4、使用socket的write函数向客户端发送数据
socket->write(data);

5、当socket接收缓冲区有新数据到来时,会发出readyRead()信号,因此为该信号添加槽函数以读取数据
connect(socket, SIGNAL(readyRead()), this, SLOT(socket_read_data()));

viod Client::socket_read_data()
{
	QByteArray buffer;
	//获取缓冲区数据
	buffer = socket->readAll();
}

6、取消侦听
socket->close();
//

(3)图解过程


2、客户端程序

(1).pro文件中加上 network

//
QT       += network
//

(2)client.h头文件代码

//
#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include <QTcpSocket>
#include <iostream>

namespace Ui {
class Client;
}

class Client : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pb_connect_clicked();
    void on_pb_send_clicked();
    void socket_read_data();
    void socket_disconnected();

private:
    Ui::Client *ui;
    QTcpSocket *tcpSocket;
};

#endif // CLIENT_H
//

(3)client.cpp源文件代码

//
#include "client.h"
#include "ui_client.h"

Client::Client(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Client)
{
    ui->setupUi(this);
    tcpSocket = new QTcpSocket(this);

    //连接信号与槽
    connect(tcpSocket, &QTcpSocket::readyRead, this, &Client::socket_read_data);
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(socket_disconnected()));

    ui->pb_send->setEnabled(false);
    ui->le_ip->setText("127.0.0.1");
    ui->le_port->setText("7654");
}

Client::~Client()
{
    delete this->tcpSocket;
    delete ui;
}

void Client::on_pb_connect_clicked()
{
    if(ui->pb_connect->text() == tr("连接"))
    {
        QString ip;
        int port;

        //获取IP地址
        ip = ui->le_ip->text();
        //获取端口号
        port = ui->le_port->text().toInt();

        //取消已有的连接
        tcpSocket->abort();
        //连接服务器
        tcpSocket->connectToHost(ip, port);

        //等待链接成功
        if(!tcpSocket->waitForConnected(30000))
        {
            std::cout << "connect error!" << std::endl;
            return;
        } else {
            std::cout << "connect success!" << std::endl;
        }

        //发送按键使能
        ui->pb_send->setEnabled(true);
        //修改按键文字
        ui->pb_connect->setText("断开连接");\

    } else {
        //断开连接
        tcpSocket->disconnectFromHost();
        //修改按键文字
        ui->pb_connect->setText("连接");
        ui->pb_send->setEnabled(false);
    }
}

void Client::on_pb_send_clicked()
{
    QString str = ui->te_send->toPlainText();
    qDebug() << str ;
    //获取文本框的内容并以ASCII码形式发送
    tcpSocket->write(ui->te_send->toPlainText().toLatin1());
    tcpSocket->flush();
}

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

void Client::socket_disconnected()
{
    //发送按键失能
    ui->pb_send->setEnabled(false);
    //修改按键文字
    ui->pb_connect->setText("连接");
    std::cout << "Disconnected !" << std::endl;
}
//

3、服务端程序

(1).pro文件中加上 network

//
QT       += network
//

(2)server.h头文件代码

//
#ifndef SERVER_H
#define SERVER_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <iostream>
#include <QDebug>

namespace Ui {
class Server;
}

class Server : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pb_listen_clicked();
    void on_pb_send_clicked();
    void socket_read_data();
    void socket_disconnected();
    void server_new_connect();

private:
    Ui::Server *ui;
    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
};

#endif // SERVER_H
//

(3)server.cpp源文件代码

//
#include "server.h"
#include "ui_server.h"

Server::Server(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Server)
{
    ui->setupUi(this);
    tcpServer = new QTcpServer(this);
    tcpSocket = new QTcpSocket(this);

    ui->le_port->setText("7654");
    ui->pb_send->setEnabled(false);

    //连接信号槽
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(server_new_connect()));

}

Server::~Server()
{
    tcpServer->close();
    tcpServer->deleteLater();
    delete ui;
}

void Server::on_pb_listen_clicked()
{
    if(ui->pb_listen->text() == tr("侦听"))
    {
        //从输入框获取端口号
        int port = ui->le_port->text().toInt();
        //监听指定的端口
        if(!tcpServer->listen(QHostAddress::Any, port))
        {
            //若出错,则输出错误信息
            qDebug() << tcpServer->errorString();
            return;
        }
        //修改按键文字
        ui->pb_listen->setText("取消侦听");
        qDebug() << "Listen success!";
    } else {
        //如果正在连接(点击侦听后立即取消侦听,若socket没有指定对象会有异常,应修正——2017.9.30)
        if(tcpSocket->state() == QAbstractSocket::ConnectedState)
        {
            //关闭连接
            tcpSocket->disconnectFromHost();
        }
        //取消侦听
        tcpServer->close();
        //修改按键文字
        ui->pb_listen->setText("侦听");
        //发送按键失能
        ui->pb_send->setEnabled(false);
    }
}

void Server::on_pb_send_clicked()
{
    qDebug() << "Send: " << ui->te_send->toPlainText();
    //获取文本框内容并以ASCII码形式发送
    tcpSocket->write(ui->te_send->toPlainText().toLatin1());
    tcpSocket->flush();
}

void Server::server_new_connect()
{
    //获取客户端连接
    tcpSocket = tcpServer->nextPendingConnection();
    //连接QTcpSocket的信号槽,以读取新数据
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(socket_read_data()));
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(socket_disconnected()));
    //发送按键使能
    ui->pb_send->setEnabled(true);

    qDebug() << "A Client connect!";
}

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

void Server::socket_disconnected()
{
    //发送按键失能
    ui->pb_send->setEnabled(false);
    qDebug() << "Disconnected!";
}
//

4、运行结果


5、工程代码

(1)工程分享


致谢

1、QT5实现简单的TCP通信

2、QT编写TCP入门+简单的实际项目(附源程序)

3、QTcpServer、QTcpSocket、QUdpSocket在聊天程序上的应用




查看评论

qt 学习笔记 qt学习笔记

  • 2010年03月27日 20:56
  • 3.77MB
  • 下载

TCP/IP详解学习笔记(9)-TCP协议概述

终于看到了TCP协议,这是TCP/IP详解里面最重要也是最精彩的部分,要花大力气来读。前面的TFTP和BOOTP都是一些简单的协议,就不写笔记了,写起来也没啥东西。TCP和UDP处在同一层---运输层...
  • goodboy1881
  • goodboy1881
  • 2006-05-16 13:35:00
  • 27665

QT学习笔记_经验篇.doc

  • 2011年05月25日 08:53
  • 616KB
  • 下载

Qt webkit 学习笔记

  • 2012年10月11日 21:51
  • 295KB
  • 下载

【机器学习-斯坦福】学习笔记6 - 朴素贝叶斯

本次课程大纲: 1、 朴素贝叶斯 - 朴素贝叶斯事件模型 2、 神经网络(简要) 3、 支撑向量机(SVM)铺垫 – 最大间隔分类器...
  • maverick1990
  • maverick1990
  • 2013-11-14 12:41:37
  • 4983

TCP-IP学习笔记-- 浅析TCP(1)

TCP的特点 TCP报文格式 TCP可靠数据传输机制数据序号和确认号机制 特点 TCP连接的建立与终止 建立连接三次握手 终止连接四次挥手 TCP的状态转换图 TCP的流量控制 工作原理 TCP拥塞控...
  • Yvonne8_5
  • Yvonne8_5
  • 2016-02-20 23:27:32
  • 1035

Qt tcp通信简单实现

功能:Qt前台界面作为客户端,linux后台程序作为服务端,客户端发送字符串给服务端,服务端返回大写 前台界面实现:通过Qt designer生成    (地址映射:10.200.1.46:199...
  • fjgui
  • fjgui
  • 2016-03-04 21:21:08
  • 3881

QT学习资源

  • 2014年05月22日 18:03
  • 943KB
  • 下载

QT总结之TCP连接

QT,tcp
  • sinat_21352339
  • sinat_21352339
  • 2017-06-16 21:05:42
  • 653

QT5实现简单的TCP通信

这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信的小例程。 使用QT的网络套接字需要.pro文件中加入一句: QT += network 一、客...
  • u014695839
  • u014695839
  • 2017-04-11 00:43:20
  • 12609
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 12万+
    积分: 4600
    排名: 7982
    博客专栏
    最新评论