#include "dlink.h" #include #include "QDateTime" #include "QThread" DLink::DLink(QObject *parent) : QObject(parent) { QTimer *Timer = new QTimer(this); Timer->setInterval(1000); //定时刷新每个接口的通讯状态 connect(Timer,&QTimer::timeout,this,[=](){ static qint64 last = QDateTime::currentMSecsSinceEpoch(); qint64 time = QDateTime::currentMSecsSinceEpoch() - last; if(time >= 1000) { foreach(clientNode node,sockets) { if(node.sock) { node.in.total += node.in.count; node.out.total += node.out.count; node.in.rate = (double)node.in.count / (time * 0.001); node.out.rate = (double)node.out.count / (time * 0.001); node.in.frequency = (double)node.in.frame / (time * 0.001); node.out.frequency = (double)node.out.frame / (time * 0.001); emit status(node.addr,node.port,node.in.total,node.in.rate,node.in.frequency,node.out.total,node.out.rate,node.out.frequency); node.in.count = 0; node.out.count = 0; node.in.frame = 0; node.out.frame = 0; sockets.replace(sockets.indexOf(node),node); //qDebug() << node.out.rate << node.out.frequency; } } last = QDateTime::currentMSecsSinceEpoch(); } }); connect(this,&DLink::destroyed,Timer,&QTimer::deleteLater); Timer->start(); } DLink::~DLink() { foreach (serialNode node, serials) { if(node.port) { if(node.port->isOpen()) { node.port->close(); } delete node.port; node.port = nullptr; } } foreach(clientNode node,sockets) { if(node.sock) { node.sock->leaveMulticastGroup(node.addr); node.sock->abort(); qWarning("leave multicast Group"); delete node.sock; node.sock = nullptr; } } disconnect(this, nullptr, nullptr, nullptr); } void DLink::transmit(QHostAddress ip,quint16 port,QByteArray data) { //qDebug() << "dlink transmit:" << QThread::currentThreadId(); QElapsedTimer time; time.start(); foreach(clientNode node,sockets) { if((node.addr == ip) && (node.port == port)) { qint64 flag = node.sock->writeDatagram(data,node.addr, node.port); if(flag != -1) { node.out.count += flag; node.out.frame += 1; sockets.replace(sockets.indexOf(node),node); } else { qDebug() << "udp Send Msg failure"; } } } //qDebug() << "dlink transmit time:" << time.nsecsElapsed() / 1000000.0 ; } void DLink::transmit(QString name,QByteArray data) { //qDebug() << "dlink transmit:" << QThread::currentThreadId(); QElapsedTimer time; time.start(); foreach (serialNode node, serials) { if((node.port)&&(node.name == name)) { if(node.port->isOpen()||node.port->isWritable()) { if(node.type == devtype::datalink) { qint64 flag = node.port->write(data); if(flag != -1) { //qDebug() << data.toHex(); node.out.count += flag; node.out.frame += 1; serials.replace(serials.indexOf(node),node); } else { qDebug() << "serialPort Send Msg failure"; } } } } } //qDebug() << "dlink transmit time:" << time.nsecsElapsed() / 1000000.0 ; } int DLink::SendMessageTo(quint8 ch, quint8 *msg, quint16 len) { //让这个函数在其他线程运行 outCount += len; //qDebug() << "Send Msg"; //更加ch选择 foreach(clientNode node,sockets) { if(node.sock->isOpen()||node.sock->isWritable()||node.sock->isValid()) { if(node.type == devtype::datalink) { qint64 flag = node.sock->writeDatagram((const char *)msg,len,node.addr, node.port); if(flag != -1) { node.out.count += flag; node.out.frame += 1; sockets.replace(sockets.indexOf(node),node); } else { qDebug() << "udp Send Msg failure"; } } } } foreach (serialNode node, serials) { if(node.port) { if(node.port->isOpen()||node.port->isWritable()) { if(node.type == devtype::datalink) { qint64 flag = node.port->write((const char *)msg,len); if(flag != -1) { node.out.count += flag; node.out.frame += 1; serials.replace(serials.indexOf(node),node); } else { qDebug() << "serialPort Send Msg failure"; } } } } } return outCount; } /* 新想法 * dlink 当作一个线程一直循环,一旦某一个串口连接,就会把事件循环加入其中,得到事件驱动 * 指令按下会把数据存到缓存,等待发送出去,线程就会结束 * 发起任务读写,新建一个线程,航线读取发送结束,航线线程结束 * 发起参数读写,新建一个线程,参数读取发送结束,参数线程结束 */ bool DLink::PortSetup(const QString &name, qint32 baudrate, QSerialPort::Parity parity) { bool isSuccess = false; qDebug() << "Q_INVOKABLE" << baudrate << parity; foreach (serialNode node, serials) { if(node.port) { if(node.name == name) { if(node.port->isOpen()) { node.port->close(); } //断掉所有的连接 disconnect(node.port,nullptr,nullptr,nullptr); delete node.port; node.port = nullptr; serials.removeAt(serials.indexOf(node)); } } } QSerialPort *serialPort = new QSerialPort(name,this); if (serialPort->open(QIODevice::ReadWrite)) { serialPort->setBaudRate(baudrate); serialPort->setParity(parity); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); connect(serialPort, SIGNAL(readyRead()), this, SLOT(readPendingDatagramsSerialPort()));//本线程内调用 isSuccess = true; serialNode node; node.port = serialPort; node.baud = baudrate; node.parity = parity; node.name = name; node.type = devtype::datalink; serials.append(node); emit showMessage(tr("Serial Port Open Success"),10000); qWarning() << "Serial Port Open Success"; } else { isSuccess = false; emit showMessage(tr("Serial Port Open Fail"),10000); qWarning() << "Serial Port Open Fail"; delete serialPort; serialPort = nullptr; } return isSuccess; } bool DLink::PortState(const QString &name) { bool flag = false; foreach (serialNode node, serials) { if(node.port) { if(node.name == name) { flag = true; break; } } } return flag; } bool DLink::PortStop(const QString &name) { bool flag = false; foreach (serialNode node, serials) { if(node.port) { if(node.name == name) { if(node.port->isOpen()) { qDebug() << "close" << node.name; emit showMessage(tr("%1 close").arg(node.name),10000); node.port->close(); } //断掉所有的连接 disconnect(node.port,nullptr,nullptr,nullptr); delete node.port; node.port = nullptr; serials.removeOne(node); flag = true; } } } return flag; } bool DLink::setupClient(const QHostAddress &local_addr,int local_port,const QHostAddress &remote_addr,int remote_port) { bool isSuccess = false; foreach (clientNode node, sockets) { if(node.sock) { if((node.addr == remote_addr)&&(node.port == remote_port)) { if(node.sock->isOpen()) { node.sock->leaveMulticastGroup(node.addr); node.sock->close(); } //断掉所有的连接 disconnect(node.sock,nullptr,nullptr,nullptr); node.sock->deleteLater(); //node.sock = nullptr; sockets.removeAt(sockets.indexOf(node)); } } } QUdpSocket *clientsock = new QUdpSocket(this); clientsock->setProxy(QNetworkProxy::DefaultProxy);//必须先设置不代理,否则连不上 int rst = clientsock->open(QIODevice::ReadWrite); if(rst) { if(clientsock->bind(local_addr,local_port,QAbstractSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) { connect(clientsock, SIGNAL(readyRead()), this, SLOT(readPendingDatagramsClient())); clientNode node; node.sock = clientsock; node.addr = remote_addr; node.port = remote_port; node.type = devtype::datalink; sockets.append(node); qWarning() << "UdpSocket open:" << remote_addr << local_port << remote_port; isSuccess = true; emit showMessage(tr("UdpSocket open"),10000); } else { clientsock->close(); isSuccess = false; qWarning() << "sock open failure" << clientsock->state(); delete clientsock; clientsock = nullptr; } } else { isSuccess = false; clientsock->close(); qWarning("sock is not binded."); delete clientsock; clientsock = nullptr; } return isSuccess; } bool DLink::setup_multicast_recieve(const QHostAddress &ip, const quint16 &port, QHostAddress newip, quint16 newport) { bool isSuccess = false; foreach (clientNode node, sockets) { if(node.sock) { if((node.addr == QHostAddress(ip))&&(node.port == port)) { if(node.sock->isOpen()) { if(node.sock->state() != QAbstractSocket::UnconnectedState) { node.sock->leaveMulticastGroup(node.addr); } node.sock->disconnectFromHost(); node.sock->close(); } //断掉所有的连接 disconnect(node.sock,nullptr,nullptr,nullptr); node.sock->deleteLater(); sockets.removeAt(sockets.indexOf(node)); } } } QHostAddress m_ip = ip; quint16 m_port = port; if((newip != QHostAddress("0,0,0,0")) && (newport != 0)) { m_ip = newip; m_port = newport; } QUdpSocket *clientsock = new QUdpSocket(this); clientsock->setProxy(QNetworkProxy::DefaultProxy);//必须先设置不代理,否则连不上 //clientsock->open(QIODevice::ReadWrite); if(clientsock->bind(QHostAddress::AnyIPv4,m_port,QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint))// { if (clientsock->joinMulticastGroup(QHostAddress(m_ip))) { // clientsock->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption,1024*1024*100); clientsock->setSocketOption (QAbstractSocket::ReceiveBufferSizeSocketOption, 1024*1024*100); clientsock->setSocketOption(QAbstractSocket::LowDelayOption, 1); clientsock->setSocketOption(QAbstractSocket::KeepAliveOption, 1); //clientsock->setSocketOption(QAbstractSocket::MulticastTtlOption, 10); //clientsock->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0);//禁止本机接收 clientNode node; node.sock = clientsock; node.addr = m_ip; node.port = m_port; node.type = devtype::datalink; sockets.append(node); qWarning() << "multicast open recieve:" << node.addr << node.port; isSuccess = true; connect(clientsock, SIGNAL(readyRead()), this, SLOT(readPendingDatagramsClient())); emit showMessage(tr("Bind and join the multicast group"),10000); } else { clientsock->close(); isSuccess = false; qWarning() << "sock open failure" << clientsock->state(); delete clientsock; clientsock = nullptr; emit showMessage(tr("Fail to join multicast group."),10000); } } else { isSuccess = false; clientsock->close(); qWarning("sock is not binded."); delete clientsock; clientsock = nullptr; emit showMessage(tr("Fail to bind multicast socket."),10000); } return isSuccess; } bool DLink::setup_multicast_transmit(const QHostAddress &ip,const quint16 &port, QHostAddress newip, quint16 newport) { bool isSuccess = false; foreach (clientNode node, sockets) { if(node.sock) { if((node.addr == QHostAddress(ip))&&(node.port == port)) { if(node.sock->isOpen()) { if(node.sock->state() != QAbstractSocket::UnconnectedState) { node.sock->leaveMulticastGroup(node.addr); } node.sock->disconnectFromHost(); node.sock->close(); } //断掉所有的连接 disconnect(node.sock,nullptr,nullptr,nullptr); node.sock->deleteLater(); sockets.removeAt(sockets.indexOf(node)); } } } QHostAddress m_ip = ip; quint16 m_port = port; if((newip != QHostAddress("0,0,0,0")) && (newport != 0)) { m_ip = newip; m_port = newport; } QUdpSocket *clientsock = new QUdpSocket(this); clientsock->setProxy(QNetworkProxy::DefaultProxy);//必须先设置不代理,否则连不上 clientsock->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption,1024); //clientsock->setSocketOption (QAbstractSocket::ReceiveBufferSizeSocketOption, 1024*1024*100); clientsock->setSocketOption(QAbstractSocket::LowDelayOption, 1); clientsock->setSocketOption(QAbstractSocket::KeepAliveOption, 1); clientNode node; node.sock = clientsock; node.addr = m_ip; node.port = m_port; node.type = devtype::datalink; sockets.append(node); qWarning() << "multicast open transmit:" << node.addr << node.port; isSuccess = true; emit showMessage(tr("Bind and join the multicast group"),10000); return isSuccess; } bool DLink::setup_multicast_close(const QHostAddress &ip,const quint16 &port) { bool isSuccess = false; foreach (clientNode node, sockets) { if(node.sock) { if((node.addr == QHostAddress(ip))&&(node.port == port)) { if(node.sock->isOpen()) { node.sock->close();//先关闭再退出 node.sock->leaveMulticastGroup(node.addr); } //断掉所有的连接 disconnect(node.sock,nullptr,nullptr,nullptr); node.sock->deleteLater(); sockets.removeAt(sockets.indexOf(node)); qWarning() << "multicast delete:" << node.addr << node.port; isSuccess = true; } } } return isSuccess; } void DLink::readPendingDatagramsSerialPort(void) { //QElapsedTimer time; //time.start(); QObject *obj = sender(); if(obj) { QSerialPort *serialport = qobject_cast(obj); if(serialport) { QByteArray datagram = serialport->readAll(); //inCount += datagram.size(); foreach (serialNode node, serials) { if(node.port) { if(node.port == serialport) { emit recieve(node.name,datagram); node.in.count += datagram.size(); node.in.frame +=1; serials.replace(serials.indexOf(node),node); break; } } } } } //qDebug() << "dlink recieve time:" << time.nsecsElapsed() / 1000000.0 ; } void DLink::readPendingDatagramsClient(void) { //QElapsedTimer time; //time.start(); QObject *obj = sender(); if(obj) { QUdpSocket *clientsock = qobject_cast(obj); if(clientsock) { //QUdpSocket::readChannelFinished() while (clientsock->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(clientsock->pendingDatagramSize()); QHostAddress address;//ip quint16 port;//端口号 clientsock->readDatagram(datagram.data(), datagram.size(),&address,&port); //emit recieve(address,port,datagram); foreach (clientNode node, sockets) { if(node.sock) { if(node.sock == clientsock) { emit recieve(node.addr,node.port,datagram); //qDebug() << "dlink" << QThread::currentThread(); node.in.count += datagram.size(); node.in.frame +=1; sockets.replace(sockets.indexOf(node),node); break; } } } } } } //qDebug() << "dlink recieve time:" << time.nsecsElapsed() / 1000000.0 ; }