1.Qt中TCP客户端编程

  • 对Qt编程而言,网络只是数据传输的通道
  • Qt提供了QTcpSocket类(封装了TCP协议细节);
  • 将QTcpSocket的对象当做黑盒使用,进行数据首发。

1.1QTcpSocket类的继承

1.2QTcpSocket的使用

  1. 连接服务器主机(connectToHost())
  2. 发送数据/接受数据(write()/read())
  3. 关闭连接(close())

1.3QTcpSocket的注意事项

  • 默认情况下,QTcpSocket使用异步编程的方式

    • 操作完成后立即返回(返回只代表的操作开始,不代表操作的结果,类似C语言中的回调函数以及Qt中的信号和槽机制)
    • 通过发送信号的方式返回操作的结果

2.QTcpSocket同步编程

2.1QTcpSocket提供辅助函数可完成同步编程的方式(返回值代表返回结果,平时编程使用的大多是同步编程的方式)

- waitForConnected()/waitForDisconnected()
- waitForBytesWritten()/waitForReadyRead()

2.2QTcpSocket同步编程流程

调用完功能函数(如connectToHost)立刻调用对应的同步辅助函数即实现同步编程

2.3QTcpSocket同步编程代码

代码运行时需启动socket的服务程序模拟tcp服务端

#include "clientdemo.h"
#include <QtGui/QApplication>
#include <QTcpSocket>
#include <QDebug> void SyncClientDemo()
{
QTcpSocket client;
char buf[256] = {0}; client.connectToHost("127.0.0.1", 8080); qDebug() << "Connected:" << client.waitForConnected(); qDebug() << "Send Bytes:" << client.write("D.T.Software"); qDebug() << "Send Status:" << client.waitForBytesWritten(); qDebug() << "Data Available:" << client.waitForReadyRead(); qDebug() << "Received Bytes:" << client.read(buf, sizeof(buf)-1); qDebug() << "Received Data:" << buf; client.close(); // client.waitForDisconnected();
} int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SyncClientDemo();
//ClientDemo w;
//w.show();
return a.exec();
}

结果

3.QTcpSocket异步编程

3.1 QTcpSocket的异步编程

  • QTcpSocket的对象通过发送信号的方式返回操作结果
  • 可以在程序中将对应的信号连接到槽函数,获取结果
  • 在GUI应用程序中通常使用QTcpSocket的异步编程方式

3.2QTcpSocket中的关键信号

  • connected():成功连接远端主机
  • disconnected:远程主机断开连接
  • readyRead():远端主机数据到达本机
  • bytesWritten(qint64):数据成功发送至系统(OS)

3.3编程实践

clientdemo.h

#ifndef CLIENTDEMO_H
#define CLIENTDEMO_H #include <QObject>
//#include "ui_clientdemo.h"
#include <QTcpSocket> class ClientDemo : public QObject
{
Q_OBJECT QTcpSocket m_client;
protected slots:
void onConnected();
void onDisconnected();
void onDataReady();
void onBytesWritten(qint64 bytes); public:
qint64 send(const char* data, int len);
qint64 available();//得到到达本机的数据长度
ClientDemo(QObject *parent = NULL);
void connectToHost(QString ip,int port);
void close();
~ClientDemo(); private:
// Ui::ClientDemoClass ui;
}; #endif // CLIENTDEMO_H

clientdemo.cpp

#include "clientdemo.h"
#include <QDebug> ClientDemo::ClientDemo(QObject *parent): QObject(parent)
{
//ui.setupUi(this); connect(&m_client, SIGNAL(connected()), this, SLOT(onConnected()) );
connect(&m_client, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
connect(&m_client, SIGNAL(readyRead()), this, SLOT(onDataReady()));
connect(&m_client, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64))); }
void ClientDemo::onConnected()
{
qDebug() << "onConnected";
qDebug() << "Local Address:" ;//<< m_client.localAddress();
qDebug() << "Local Port:" << m_client.localPort();
} void ClientDemo::onDisconnected()
{
qDebug() << "onDisconnected";
} void ClientDemo::onDataReady()
{
char buf[256] = {0};
qDebug() << "onDataReady:" << m_client.read(buf, sizeof(buf)-1);
qDebug() << "Data:" << buf;
} void ClientDemo::onBytesWritten(qint64 bytes)
{
qDebug() << "onBytesWritten:" << bytes;
} void ClientDemo::connectToHost(QString ip,int port)
{
m_client.connectToHost(ip, port);
} qint64 ClientDemo::send(const char* data, int len)
{
return m_client.write(data, len);
} qint64 ClientDemo::available()
{
return m_client.bytesAvailable();
} void ClientDemo::close()
{
m_client.close();
} ClientDemo::~ClientDemo()
{ }

main.cpp

#include "clientdemo.h"
#include <QtGui/QApplication>
#include <QTcpSocket>
#include <QDebug> int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//SyncClientDemo();
ClientDemo w;
w.connectToHost("127.0.0.1",8080);
char buf[]="abc";
w.send(buf,sizeof(buf)-1);
//w.show();
return a.exec();
}

结果



4.小结

  • Qt提供了QTcpSocket类,其对象可用于收发TCP数据
  • QTcpSocket默认使用异步编程方式
  • QTcpSocket提供辅助函数用于完成同步编程的方式
  • GUI应用程序通常使用QTcpSocket的异步编程方式

TCP 客户端编程的更多相关文章

  1. android 之TCP客户端编程

    补充,由于这篇文章是自己入门的时候写的,随着Android系统的升级可能有发送需要在任务 中进行,如有问题请百度 thread 或者看下面链接的文章 https://www.cnblogs.com/y ...

  2. Android之TCP服务器编程

    推荐一个学java或C++的网站http://www.weixueyuan.net/,本来想自己学了总结出来再写博客,现在没时间,打字太慢!!!!,又想让这好东西让许多人知道. 关于网络通信:每一台电 ...

  3. python网络编程socketserver模块(实现TCP客户端/服务器)

    摘录python核心编程 socketserver(python3.x版本重新命名)是标准库中的网络编程的高级模块.通过将创建网络客户端和服务器所必须的代码封装起来,简化了模板,为你提供了各种各样的类 ...

  4. 系统编程-网络-tcp客户端服务器编程模型(续)、连接断开、获取连接状态场景

    相关博文: 系统编程-网络-tcp客户端服务器编程模型.socket.htons.inet_ntop等各API详解.使用telnet测试基本服务器功能 接着该上篇博文,咱们继续,首先,为了内容的完整性 ...

  5. --系统编程-网络-tcp客户端服务器编程模型、socket、htons、inet_ntop等各API详解、使用telnet测试基本服务器功能

    PART1 基础知识 1. 字节序 网络字节序是大端字节序(低地址存放更高位的字节), 所以,对于字节序为小端的机器需要收发网络数据的场景,要对这些数据进行字节序转换. 字节序转换函数,常用的有四个: ...

  6. Python--网络编程学习笔记系列02 附:tcp服务端,tcp客户端

    Python--网络编程学习笔记系列02 TCP和UDP的概述: udp通信模型类似于写信,不需要建立相关链接,只需要发送数据即可(现在几乎不用:不稳定,不安全) tcp通信模型类似于打电话,一定要建 ...

  7. Java网络编程(TCP客户端)

    TCP传输:两个端点建立连接后会有一个传输数据的通道,这个通道就称为流,而且是建立在网络基础上的流,之为socket流,该流中既可以读取也可以写入. TCP的两个端点:一个客户端:ServerSock ...

  8. python编程系列---tcp客户端的简单实现

    实现流程如下: """ TCP客户端实现流程1. 创建一个tcp 客户端对象2. 与服务端建立连接3. 通过tcp socket 收发数据4. 关闭连接 关闭tcp &q ...

  9. TCP客户端服务器编程模型

    1.客户端调用序列 客户端编程序列如下: 调用socket函数创建套接字 调用connect连接服务器端 调用I/O函数(read/write)与服务器端通讯 调用close关闭套接字 2.服务器端调 ...

随机推荐

  1. 通过 Ajax 调取后台接口将返回的 json 数据绑定在页面上

    第一步: 编写基础的 html 框架内容,并引入 jquery: <!doctype html> <html lang="en"> <head> ...

  2. Linux操作系统常用命令合集——第四篇-文件系统权限操作(5个命令)

    1.umask [命令作用] 文件或目录创建时的遮罩码 [命令语法] umask     [选项]    [参数] [常用选项] -p  --输出的权限掩码可直接作为指令来执行 -s  --以符号方式 ...

  3. pyexcel_xlsx

    from pyexcel_xlsx import get_data,save_data excel_data = get_data('xxxx.xlsx文件存储位置') #得到的excel_data是 ...

  4. Xmind8安装

    现在新版安装极其简单.是deb安装包Xmind8安装小书匠 kindle 参照官网安装方法,在此记录下来,方便自己查找. 流程: 55ccaad0655d256ac5fb9fea8aa8569d.pn ...

  5. 关于解决ruby源码安装 gem install报错问题

    因做redis集群需要安装ruby,源码安装过后gem install redis安装redis接口报错 解决方案: 确保主机安装zlib,没有安装执行 yum -y install zlib zli ...

  6. zookpeer 和 redis 集群内一致性协议 及 选举 对比

    zookeeper 使用的是zab协议,类似 raft 的 Strong Leader 模式 redis 的哨兵 在  崩溃选举的时候采用的是 raft的那一套term. 因为redis 采用的是异步 ...

  7. Spring源代码分析:PropertiesLoaderSupport

    概述 Spring PropertiesLoaderSupport是一个抽象基类,它抽象了从不同渠道加载属性的通用逻辑,以及这些属性应用优先级上的一些考虑.它所提供的这些功能主要供实现子类使用.Spr ...

  8. Java的反射是什么?有什么用?

    首先我要简单的来说一下什么是Java的反射机制: 在Java里面一个类有两种状态--编译和运行状态,通常我们需要获取这个类的信息都是在编译阶段获得的,也就是直接点出来或者new出来,可是如果需要在类运 ...

  9. Factor_Analysis

    Factor_Analysis(因子分析) Factor Analysis 简书:较好理解的解释,其中公式有一定的推导(仅展现关键步骤,细节大多需要自行补充),基本为结论式. 感性层面理解:首先,明确 ...

  10. linux nand flash常用命令

    使用命令前用cat /proc/mtd 查看一下mtdchar字符设备:或者用ls -l /dev/mtd*#cat /proc/mtddev:    size   erasesize  namemt ...