前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >qtcpsocket 客户端_qtcpsocket接收结构体数据

qtcpsocket 客户端_qtcpsocket接收结构体数据

作者头像
全栈程序员站长
发布2022-09-30 10:24:30
1.3K0
发布2022-09-30 10:24:30
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

实现tcp客户端通信并支持keepAlive探测包

代码语言:javascript
复制
#pragma once

#include <QObject>
#include <QTcpSocket>
/**********************************************
* 作者:wujianhua
* 时间:2021/02/25
* 类介绍:socket tcp客户端通信类
*
***********************************************/
class TcpClient : public QObject
{
	Q_OBJECT

public:
	TcpClient(QObject *parent);
	~TcpClient();
	
	/**********************************************
	* 作者:wujianhua
	* 时间:2021/02/25
	* 函数:连接服务器
	* 参数:
	*	ip:服务器地址
	*	port:服务器端口
	*	timeout:超时时间
	* 返回:
	*	连接成功返回true,失败返回false
	***********************************************/
	bool connect(const QString ip, int port, int timeout = 3000);

	/**********************************************
	* 作者:wujianhua
	* 时间:2021/02/25
	* 函数:断开服务器连接
	* 参数:
	*	无
	* 返回:
	*	无
	***********************************************/
	void disconnect();
	
	/**********************************************
	* 作者:wujianhua
	* 时间:2021/02/25
	* 函数:是否连接
	* 参数:
	*	无
	* 返回:
	*	返回true为连接状态,false为断开状态
	***********************************************/
	bool isOnline();
	
	/**********************************************
	* 作者:wujianhua
	* 时间:2021/02/25
	* 函数:发送数据
	* 参数:
	*	dat:数据对象
	* 返回:
	*	发送成功返回对应发的字节数,-1设备未连接
	***********************************************/
	int send(QByteArray dat);
	
	/**********************************************
	* 作者:wujianhua
	* 时间:2021/02/25
	* 函数:接收设备发送过来的数据
	* 参数:
	*	buf:接收设备发送的数据缓存
	*	timeout:超时时间
	* 返回:
	*	返回接收到的数据字节数,-1设备未连接
	***********************************************/
	int recv(QByteArray &buf, int timeout = 10*1000);

	/**********************************************
	* 作者:wujianhua
	* 时间:2021/03/02
	* 函数:设置心跳保活机制
	* 参数:
	*	keepIdle:没有数据交互后发送心跳探测包 单位秒
	*	keepInterval:探测包间隔时间 单位秒
	*	keepCount:探测重试次数
	* 返回:
	*	无
	***********************************************/
	void setKeepAlive(int keepIdle = 2, int keepInterval = 1, int keepCount = 3);

private slots:
	void slot_connected();
	void slot_readData();
	void slot_disconnected();
	void slot_stateChange(QAbstractSocket::SocketState state);
private:
	QTcpSocket *_tcp = nullptr;
	QString _ip;
	int _port;
	bool _online = false;
	QByteArray _readbuf;
};
代码语言:javascript
复制
#include "TcpClient.h"
#include <QSettings>
#include <QDebug>
#ifdef Q_OS_WIN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <ws2ipdef.h>
#include <mstcpip.h>
#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")
#endif // Q_OS_WIN
#ifdef Q_OS_LINUX
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#endif // Q_OS_LINUX
TcpClient::TcpClient(QObject *parent)
: QObject(parent){
_tcp = new QTcpSocket(this);
QObject::connect(_tcp, &QAbstractSocket::connected, this, &TcpClient::slot_connected);
QObject::connect(_tcp, &QIODevice::readyRead, this, &TcpClient::slot_readData);
QObject::connect(_tcp, &QAbstractSocket::disconnected, this, &TcpClient::slot_disconnected);
QObject::connect(_tcp, &QAbstractSocket::stateChanged, this, &TcpClient::slot_stateChange);
}
TcpClient::~TcpClient() {
disconnect();
delete _tcp;
_tcp = nullptr;
}
bool TcpClient::connect(const QString ip, int port, int timeout /*= 3000*/){
disconnect();
_tcp->abort();
_ip = ip;
_port = port;
_tcp->connectToHost(_ip, _port);
_tcp->waitForConnected(timeout);
if (_online) {
setKeepAlive();
}
return _online;
}
void TcpClient::disconnect(){
if (_online) {
_tcp->disconnectFromHost();
}
}
bool TcpClient::isOnline(){
return _online;
}
int TcpClient::send(QByteArray dat){
int size = -1;
if (_online) {
size = _tcp->write(dat);
_tcp->flush();
}
return size;
}
int TcpClient::recv(QByteArray &buf, int timeout /* = 10*1000 */){
int size = -1;
if (_online) {
_tcp->waitForReadyRead(timeout);
size = _readbuf.size();
buf = _readbuf;
}
return size;
}
void TcpClient::setKeepAlive(int keepIdle /* = 2 */, int keepInterval /* = 1 */, int keepCount /* = 3 */){
//设置keepAlive心跳检测
int fd = _tcp->socketDescriptor();
int keepAlive = 1;		//开启keepAlive属性
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&keepAlive, sizeof(keepAlive));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, (char*)&keepIdle, sizeof(keepIdle));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&keepInterval, sizeof(keepInterval));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, (char*)&keepCount, sizeof(keepCount));
}
void TcpClient::slot_connected(){
_online = true;
}
void TcpClient::slot_readData(){
_readbuf = _tcp->readAll();
}
void TcpClient::slot_disconnected(){
_online = false;
}
void TcpClient::slot_stateChange(QAbstractSocket::SocketState state){
switch (state){
case QAbstractSocket::UnconnectedState:
_online = false;
break;
case QAbstractSocket::ConnectedState:
_online = true;
break;
default:
break;
}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月9日 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档