-
2021-11-13 17:41:57
前言
通过QT的两个类(QTcpSocket)和(QTcpServer)来实现TCP通信。
这两个类属于Qt Network模块,所以先在项目文件中添加QT += network。
.proQT += network
一、TCP服务端
第一种创建方式
在服务器应用程序中,创建一个QTcpServer类对象。调用QTcpServer::listen () 设置服务器,并连接到QTcpServer::newConnection () 信号,该信号每个新连接的客户端发出一次。并调用QTcpServer::nextPendingConnection () 接受连接并使用返回的QTcpSocket与客户端进行通信。
void MainWindow::my_TcpServer(int port) { server = new QTcpServer(); //创建一个QTcpServer类对象 server->listen(QHostAddress::Any, port); //监听 connect(server,&QTcpServer::newConnection,this,&MainWindow::do_newConnect); } void MainWindow::do_newConnect() { //获取客户端连接 socket = server->nextPendingConnection(); }
第二种创建方式
基于QTcpServer类,创建一个子类,通过该写QTcpServer类中Protected Functions的虚函数
来实现一些自己想要的内容。
virtual void incomingConnection(qintptr socketDescriptor)
当新连接可用时,QTcpServer会调用此虚拟函数。该socketDescriptor参数是接受的连接本地套接字描述符。
基本实现创建一个QTcpSocket,设置套接字描述符,然后将QTcpSocket存储在挂起连接的内部列表中。最后发出newConnection ()。
重新实现此函数以在连接可用时更改服务器的行为。
在这里我们改写这个函数:Server::Server(QObject *parent, int port):QTcpServer(parent) { listen(QHostAddress::Any, port); //监听 } void Server::incomingConnection(int socketDescriptor) { //生成一个新的通信套接字 TcpSocket *tcpsocket = new TcpClientSocket(this); //将新创建的通信套接字描述符指定为参数socketdescriptor tcpsocket->setSocketDescriptor(socketDescriptor); //将这个套接字加入客户端套接字列表中 tcpsocketlist.append(tcpsocket); //将这个套接字添加到 Pending Connections 机制中。 addPendingConnection (tcpsocket); /* 需要添加的内容 比如:接收数据和判断连接状态 //客户端发送数据过来就会触发readyRead信号 connect(tcpsocket, &TcpSocket::readyRead, this, &Server::receivedata); //客户端断开连接触发disconnected信号 connect(tcpsocket, &TcpSocket::disconnected, this, &Server::slotclientdisconnected); */ } void Server::sendDataToClient(QByteArray myData) { if (!tcpsocketlist.empty()){ //发送数据给客户端,从套接字列表中找到需要接收的套接字 for(int i = 0; i < tcpsocketlist.count(); i++) { QTcpSocket *item = tcpclientsocketlist.at(i); item->write(myData); } } }
然后在主程序创建Server对象和绑定自己设置的信号就行
void MainWindow::init_tcp() { my_server = new Server(this,9003); connect(my_server, &Server::update, this, &MainWindow::do_update); }
二、TCP客户端
TCP客户端相对简单;
创建套接字
socket = new QTcpSocket();
连接服务器
socket->connectToHost(ip, port);
发送数据
socket->write(myData);总结
具体程序见:https://download.csdn.net/download/qq_39641107/41320871
上面是我运用QT的TCP类,建立的TCP通信。
如有错误希望请大家指导,谢谢点赞!
希望和大家一起学习,交流!更多相关内容 -
QT通信-串口通信
2021-11-12 17:24:12QT通信-串口通信前言一、串口搜索二、打开串口二、发送或接收数据二、程序如下:总结 前言 QT 串口通信基于QT的QSerialPort类,先在项目文件pro中添加QT += serialport。 我使用的是ubuntu16.04,window下未测试是否...
前言
QT 串口通信基于QT的QSerialPort类,先在项目文件pro中添加QT += serialport。
我使用的是ubuntu16.04,window下未测试是否能用。
QT的QSerialPort类说明见官网一、串口搜索
使用QT串口通信类中QSerialPortInfo类的availablePorts()来获取计算机存在的串口。
初始化串口对象m_serialPort = new QSerialPort();//实例化串口类一个对象
foreach是for的简化式,主要用于循环次数未知,这里获取的串口数目未知,将串口名称存放在QStringList中。
//选择串口 void CommuncationCenter::serial_select() { foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { m_serialPortName << info.portName(); QString c= "串口:"; emit(error_log(c+info.portName())); } if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了 { m_serialPort->clear(); m_serialPort->close(); } }
二、打开串口
选择QStringList中的串口名称,通过setPortName(QString)来设置打开那个串口,使用open(QIODevice::ReadWrite)用ReadWrite 的模式尝试打开串口,打开成功后设置串口通信的波特率,校验方式等配置。(打开方式有多种,只读(r/o)、只写(w/o)或读写(r/w)模式)
m_serialPort->setPortName(m_serialPortName[0]); if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口 { c = "打开失败!:"; emit(error_log(c+m_serialPortName[i])); return false; } else { m_serialPort->setBaudRate(my_baud,QSerialPort::AllDirections);//设置波特率和读写方向 m_serialPort->setDataBits(QSerialPort::Data8); //数据位为8位 m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制 m_serialPort->setParity(QSerialPort::NoParity); //无校验位 m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位 //连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号,我们定义个槽void receiveInfo()解析数据 connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo())); connect(timer, SIGNAL(timeout()), this, SLOT(timeUpdate())); c = "打开成功!:"; emit(error_log(c+m_serialPortName[i]));
注意:串口始终以独占访问方式打开(即没有其他进程或线程可以访问已打开的串口)。
二、发送或接收数据
使用read () 和write () ,也可以调用readLine () 和readAll () 。如果不是一次读取所有数据,剩余的数据将在以后可用,因为新的传入数据将附加到 QSerialPort 的内部读取缓冲区。也可以使用setReadBufferSize ()限制读取缓冲区的大小。
从串口读取数据:QByteArray info = m_serialPort->readAll();
发送数据给串口:m_serialPort->write(info,len);二、程序如下:
.h:
#ifndef COMMUNCATIONCENTER_H #define COMMUNCATIONCENTER_H #include<QtCore> #include <QObject> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <AgvTypeData.h> class CommuncationCenter : public QThread { Q_OBJECT //使用信号与槽函数 public: explicit CommuncationCenter(QObject *parent = nullptr); QStringList m_serialPortName; void run(); void serial_select();//选择串口 bool serial_port(QString my_com, qint32 my_baud);//打开串口 void sendInfo(const QString &info);//发送数据 void sendInfo(char* info,int len);//发送数据 void serial_close();//关闭串口 QString Crc16(const QString &data_str);//CRC校验 private: QSerialPort *m_serialPort; QTimer *timer; QString read_data; char convertCharToHex(char ch); void convertStringToHex(const QString &str, QByteArray &byteData); //声明信号 signals: void error_log(QString error_port); void get_data(QString read_data); void error_data(QString e_data); private slots: void receiveInfo();//接受分段数据 void timeUpdate(); //接受全部数据 }; #endif // COMMUNCATIONCENTER_H
.cpp
#include "communcationcenter.h" CommuncationCenter::CommuncationCenter(QObject *parent):QThread(parent) { m_serialPort = new QSerialPort();//实例化串口类一个对象 timer = new QTimer(); read_data = ""; } //选择串口 void CommuncationCenter::serial_select() { foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { m_serialPortName << info.portName(); QString c= "串口:"; emit(error_log(c+info.portName())); } if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了 { m_serialPort->clear(); m_serialPort->close(); } } //打开串口 bool CommuncationCenter::serial_port(QString my_com, qint32 my_baud) { if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了 { m_serialPort->clear(); m_serialPort->close(); } if (m_serialPortName[0]!=0) { //设置串口名字 假设我们上面已经成功获取到了 for(int i = 0; i < m_serialPortName.size(); i++) { if (m_serialPortName[i] == my_com) { QString c= "找到匹配的串口::"; emit(error_log(c+m_serialPortName[i])); m_serialPort->setPortName(m_serialPortName[0]); if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口 { c = "打开失败!:"; emit(error_log(c+m_serialPortName[i])); return false; } else { m_serialPort->setBaudRate(my_baud,QSerialPort::AllDirections);//设置波特率和读写方向 m_serialPort->setDataBits(QSerialPort::Data8); //数据位为8位 m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制 m_serialPort->setParity(QSerialPort::NoParity); //无校验位 m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位 //连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号,我们定义个槽void receiveInfo()解析数据 connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo())); connect(timer, SIGNAL(timeout()), this, SLOT(timeUpdate())); c = "打开成功!:"; emit(error_log(c+m_serialPortName[i])); return true; } } } } QString c= "没有找到匹配的串口!"; emit(error_log(c)); return false; } void CommuncationCenter::run() { } //串口接收单片机的数据 void CommuncationCenter::receiveInfo() { timer->start(100);//启动定时器,接收100毫秒数据(根据情况设定) QByteArray info = m_serialPort->readAll(); QByteArray heData = info.toHex(); QString hexData(heData); read_data = read_data+hexData; //这里面的协议 你们自己定义就行 单片机发什么 代表什么 我们这里简单模拟一下 } void CommuncationCenter::timeUpdate() { timer->stop(); if(read_data.size()!=0) { if(read_data == "010000") { emit(error_log("do"+read_data));//do something } else if(read_data == "100001") { emit(error_log("you"+read_data));//do something } else{ emit(error_log(read_data)); emit(get_data(read_data));//发送数据给主线程 } } read_data = ""; } //串口向单片机发送数据====================================================== //基本和单片机交互 数据 都是16进制的 我们这里自己写一个 Qstring 转为 16进制的函数 void CommuncationCenter::convertStringToHex(const QString &str, QByteArray &byteData) { int hexdata,lowhexdata; int hexdatalen = 0; int len = str.length(); byteData.resize(len/2); char lstr,hstr; for(int i=0; i<len; ) { //char lstr, hstr=str[i].toLatin1(); if(hstr == ' ') { i++; continue; } i++; if(i >= len) break; lstr = str[i].toLatin1(); hexdata = convertCharToHex(hstr); lowhexdata = convertCharToHex(lstr); if((hexdata == 16) || (lowhexdata == 16)) break; else hexdata = hexdata*16+lowhexdata; i++; byteData[hexdatalen] = (char)hexdata; hexdatalen++; } byteData.resize(hexdatalen); } //另一个 函数 char 转为 16进制 char CommuncationCenter::convertCharToHex(char ch) { /* 0x30等于十进制的48,48也是0的ASCII值,, 1-9的ASCII值是49-57,,所以某一个值-0x30,, 就是将字符0-9转换为0-9 */ if((ch >= '0') && (ch <= '9')) return ch-0x30; else if((ch >= 'A') && (ch <= 'F')) return ch-'A'+10; else if((ch >= 'a') && (ch <= 'f')) return ch-'a'+10; else return (-1); } //写两个函数 串口向单片机发送数据 void CommuncationCenter::sendInfo(char* info,int len){ for(int i=0; i<len; ++i) { printf("0x%x\n", info[i]); } m_serialPort->write(info,len);//这句是真正的给单片机发数据 用到的是QIODevice::write 具体可以看文档 } void CommuncationCenter::sendInfo(const QString &info){ QByteArray sendBuf; convertStringToHex(info, sendBuf); //把QString 转换 为 hex m_serialPort->write(sendBuf);//这句是真正的给单片机发数据 用到的是QIODevice::write 具体可以看文档 emit(error_log("发送数据成功!"+info)); } //======================================================================== //关闭串口 void CommuncationCenter::serial_close() { if (m_serialPort->isOpen()) { m_serialPort->close(); } delete m_serialPort; } //====================CRC校验==================================== QString CommuncationCenter::Crc16(const QString &data_str) { quint8 buf; quint16 crc16 = 0xFFFF; QByteArray data; convertStringToHex(data_str, data); //把QString 转换 为 hex for ( auto i = 0; i < data.size(); ++i ) { buf = data.at( i ) ^ crc16; crc16 >>= 8; crc16 ^= crc16Table[ buf ]; } QString str = QString::number(crc16,16).toUpper(); qDebug()<<"CRC校验"<<str; return str; }
总结
QT的串口通信程序可能有沉余代码,可以更加简洁,谢谢大家点赞及指导!
希望和大家一起学习,交流! -
QTWebChat_JS:一个基于QT WebEngine和WebChannel的JS和QT通信例子
2021-05-02 05:02:47QTWebChat 一个QT和JS通信的样例, 这是前端部分。 本项目只是一个样例,仅供学习参考使用。 -
Qt通信协议程序.rar
2021-04-23 17:16:40TCP、UDP以及串口通信的Qt代码 -
QT应用程序与web页面通信
2020-10-28 11:07:41QT应用程序与嵌入浏览器web页面通信源代码,相互发送/接收数据。 -
qt串口通信,实现发送和接收
2018-12-07 10:02:02Qt使用自带类实现串口通信,包括串口的发送数据和串口的接收数据 -
qt实现QQ通信
2018-06-08 21:50:07qt实现QQ通信,创建群实现聊天............................................................................................................................................ -
zeromq+qt通信源码
2014-04-29 17:34:08zeromq与qt的client与server通信源码 -
电信设备-实现VxWorks与Qt通信的消息队列方法.zip
2021-09-18 23:49:08电信设备-实现VxWorks与Qt通信的消息队列方法.zip -
QT5.9 serialport串口通信模块,编写一个上位机程序,串口调试助手,附源码
2019-04-04 10:50:58利用QT5.9 serialport串口通信模块编写串口调试助手,exe文件可直接运行,附源码。详见 https://blog.csdn.net/qq_43569273/article/details/89015593 -
Qt5网络与通信.pdf
2020-03-20 13:00:52Qt5系统学习之网络与通信,文档共58页,包含如下内容 1、获取本机网络信息 2、基于UDP的网络广播程序 3、基于TCP的网络聊天室程序 4、Qt网络应用开发初步 -
基于Qt的Can通信代码
2020-05-26 21:24:32在基于Qt的平台下实现同CAN总线的通信,使用Qt加载动态库来实现CAN通信。周立功为CAN通信提供了动态库:官方提供了很多相关动态库和lib等。其中kerneldlls里还有很多动态库,还有一个配置文件。 如果只用到USBCAN2... -
vs2015+qt串口通信开发
2021-09-23 09:49:36本程序主要是用vs2015+qt开发串口方面的应用,全部源码,适合c++开发人员 -
Qt与Arduino实战篇之LED灯控制
2021-07-01 10:21:4930分钟上手使用Qt编写可视化程序使用串口给Arduino发送消息点亮LED小项目实战。 通过学习本门课程,可以对Arduino和Qt有初步认识。 全程干货,快速上手。 -
QT串口通信程序
2018-09-25 17:54:33QT环境下写的,串口通信程序,实测通过。支持十六机制收发 -
QT socket通信,收发结构体.zip
2020-03-27 13:17:00在Qt里利用TCP/IP协议,socket套接字设计实现结构体数据的收发,类似实现简单的自定义通信协议。发送的结构体包含帧头(占两字节)、数据长度(占一字节)、数据(不多于64字节)、校验和(占一个字节)。 -
Qt 串口通信_qt串口_QTCOM_QT串口通信
2021-09-11 01:38:31讲解QT下串口编程方面的知识,并提供代码示例 -
Qt环境下实现的TCP网络通讯
2019-11-11 11:21:12在Qt环境下实现的TCP网络通讯,传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个... -
QT 蓝牙通信.zip
2019-05-27 10:38:54本资源包含两个QT工程,其中一个是服务器,一个是客户端,可实现手机和电脑的蓝牙通信 和聊天小程序,希望可以给大家借鉴。亲测可以用的。一个下载到手机,一个下载到电脑。 -
基于Qt WebChannel实现QT与HTML页面通信
2019-10-18 21:01:49最近,C++和WEB本地混合应用开发模式逐渐流行起来,个人也认为标记语言描述的界面是界面开发的一个发展趋势。...随着HTML5技术风生水起,Qt开发团队用近一年的时间开发了...本例实现基于Qt WebChannel 的QT与HTML页面通信 -
Qt实现WebSocket客户端和服务端通信
2021-05-18 17:51:35使用Qt实现WebSocket客户端与服务端之间的通信,可供初学者学习或使用 -
qt中的双向udp通信demo
2020-05-22 15:42:41单机上的双向udp通信。 在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。这里我们还要了解一个名词Socket,也就是常说的“套接字”。Socket简单地说,就是一个IP地址加一个port端口 。因为我们... -
qt 中 多线程tcp通信
2021-10-13 22:25:14一个简单的通信demo 当时做测试用的。包括客户端和服务端。 在非主线程中使用tcp的通信,基于qt编写 -
Qt实现串口通信源码
2017-03-18 10:41:17此资源是Qt实现串口通信源码,用qt模仿串口调试助手做的界面,特别适合初学者快速掌握qt。 -
Qt 串口通信(QSerialPort)16进制收发实例代码(QT实战5)
2021-01-06 06:33:30Qt 串口通信(QSerialPort)16进制收发实例代码 首先在项目文件里面添加一句 QT += serialport 使用静态函数生成QSerialPortInfo对象列表。列表中的每个QSerialPortInfo对象表示一个串行端口,可以查询端口... -
Qt串口通信的完整工程
2021-03-25 19:02:00Qt串口通信,代码与“Qt串口通信”相同,如果能够将“Qt串口通信”中的程序跑通可以不下载 -
基于Qt的局域网即时通信系统(聊天软件)
2014-08-03 22:51:12以前网上找到的一份源代码,但是忘记下载链接了。。我自己完美运行,所以上传分享给大家。供大家参考,互相讨论学习。 -
Qt进程间通信与同步示例
2020-04-29 22:02:25Qt进程间通信与同步示例,通过QFile内存映射文件来共享内存达到进程间通信的效果。同时利用QSystemSemaphore 来实现进程同步 -
Qt5网络与通信
2018-01-06 18:24:15在应用程序开发中网络编程非常重要,目前互联网通信的TCP/IP协议,自上而下分为应用层、传输层、网际层和网络接口层这四层。实际编写网络应用程序时只使用到传输层和应用层,所涉及的协议主要包括UDP、TCP、FTP和... -
Qt实现的SSL通信客户端和服务器
2020-06-24 14:00:53Qt实现的SSL通信客户端和服务器