Files
checker_host/interface/if_tcp.cpp
ranchuan 92f3ebbe33 添加tcp心跳
添加升级小板程序、方案、jwt文件的进度条命令
2023-12-29 09:41:37 +08:00

219 lines
5.3 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "if_tcp.h"
#include "QNetworkConfigurationManager"
#include "QThread"
const int keepalive = 1; // 开启keepalive属性
const int keepidle = 5; // 如果连接在5秒内没有任何数据来往则进行探测
const int keepinterval = 3; // 探测时发包的时间间隔为3秒
const int keepcount = 3; // 尝试探测的次数, 如果第一次探测包就收到响应,则不在继续探测
#if 1
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
// 开启TCP心跳检测机制
int enableKeepalive(int fd) {
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) return -1;
if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle)) < 0) return -1;
if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &keepinterval, sizeof(keepinterval)) < 0) return -1;
if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &keepcount, sizeof(keepcount)) < 0) return -1;
return 0;
}
#else
int enableKeepalive(int fd)
{
return -1;
}
#endif
static bool CheckNetInfo()
{
QNetworkInterface net= QNetworkInterface::interfaceFromName("eth0");
if(net.flags().testFlag(QNetworkInterface::IsUp)
&& net.flags().testFlag(QNetworkInterface::IsRunning)
&& !net.flags().testFlag(QNetworkInterface::IsLoopBack)
&& (net.name() == "eth0"))
{
// qDebug() << "eth0 is Connected" << endl;
return true;
}
else
{
// qDebug() << "eth0 is Not Connected";
return false;
}
}
if_tcp::if_tcp()
{
this->connect_state = false;
this->timer_reconnect_ = nullptr;
this->tcp_socket_ = nullptr;
this->reconnect_timeout_ms = 3000;
this->cfg_ = syscfg();
this->timer_recv_end_ = nullptr;
this->recv_end_timeout_ms = 100;
qDebug("tcp created.");
}
if_tcp::~if_tcp()
{
if(timer_reconnect_!=nullptr){
delete timer_reconnect_;
}
if(tcp_socket_!=nullptr){
delete tcp_socket_;
}
if(timer_recv_end_!=nullptr){
delete timer_recv_end_;
}
}
void if_tcp::init()
{
if (nullptr == timer_reconnect_)
{
timer_reconnect_ = new QTimer(this);
connect(timer_reconnect_, &QTimer::timeout, this, &if_tcp::reconnect_cb);
}
timer_reconnect_->start(reconnect_timeout_ms);
if (nullptr == tcp_socket_)
{
tcp_socket_ = new QTcpSocket(this);
connect(tcp_socket_, SIGNAL(connected()), this, SLOT(connected_cb()));
connect(tcp_socket_, SIGNAL(disconnected()), this, SLOT(disconnected_cb()));
connect(tcp_socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(state_changed_cb(QAbstractSocket::SocketState)));
connect(tcp_socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(on_error_cb(QAbstractSocket::SocketError)));
connect(tcp_socket_, SIGNAL(readyRead()), this, SLOT(ready_read_cb()));
tcp_socket_->setSocketOption(QAbstractSocket::LowDelayOption, 1); // 禁用Nagle算法.
tcp_socket_->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
if (cfg_->tcp_enable){
tcp_socket_->connectToHost(QHostAddress(cfg_->server_ip), cfg_->server_port);
enableKeepalive(tcp_socket_->socketDescriptor());
}
}
}
// 获取本机地址
QString if_tcp::get_local_ip()
{
QList<QNetworkInterface> network = QNetworkInterface::allInterfaces();
foreach (QNetworkInterface net, network)
{
QString netName = net.humanReadableName();
if (netName == "eth0")
{
QList<QNetworkAddressEntry> list = net.addressEntries(); // 获取IP地址与子掩码等
foreach (QNetworkAddressEntry address, list)
{
if (address.ip().protocol() == QAbstractSocket::IPv4Protocol) // 获取IPv4的地址
{
return address.ip().toString();
}
}
}
}
return QString();
}
void if_tcp::reconnect_cb()
{
// 网线拔出之后自动断开连接
if(CheckNetInfo()==false){
if(connect_state!=false){
connect_state=false;
tcp_socket_->close();
}
}else{
if (connect_state != true)
{
if (cfg_->tcp_enable)
{
tcp_socket_->connectToHost(QHostAddress(cfg_->server_ip), cfg_->server_port);
}
}
}
}
void if_tcp::connected_cb()
{
connect_state = true;
emit tcp_connected_signal();
qInfo("connected");
}
void if_tcp::disconnected_cb()
{
connect_state = false;
qInfo("disconnected");
}
void if_tcp::state_changed_cb(QAbstractSocket::SocketState nSocketState)
{
// qInfo("state changed:%d", nSocketState);
}
void if_tcp::on_error_cb(QAbstractSocket::SocketError nErrCode)
{
connect_state = false;
// qWarning("on error:%d", nErrCode);
}
void if_tcp::ready_read_cb()
{
QByteArray data = tcp_socket_->readAll();
if (irq_fun)
{
irq_fun(myarray(data));
}
emit tcp_recv_signal();
// qInfo()<< "recv data from tcp:"<<crc::byte_array_to_string(recv)<<endl;
}
int if_tcp::write(myarray data)
{
emit tcp_send_signal();
if (nullptr == tcp_socket_ || false == connect_state)
{
// qWarning() << "Cant send data , TcpClient socket not connect.";
return 0;
}
int wb = tcp_socket_->write(data);
if (!tcp_socket_->flush())
{
qWarning("write fial:[%s]", data.toHex(' ').data());
}
else
{
}
return wb;
}
InterFace *if_tcp_get()
{
static InterFace *if_ = nullptr;
if (if_ == nullptr)
{
if_ = new if_tcp();
QTimer::singleShot(0, if_, &InterFace::init);
}
return if_;
}
if_export(tcp, if_tcp_get);