#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 #include #include #include // 开启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 network = QNetworkInterface::allInterfaces(); foreach (QNetworkInterface net, network) { QString netName = net.humanReadableName(); if (netName == "eth0") { QList 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:"<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);