netcat doen't see but tcpdump see datagrams sent by qt-client | might be flow in app logic



  • Hi, i am working on a program which intends to send datagrams to a particular port ( port 8881 ). The program seems to work fine except the fact that datagrams sent can be seen with tcpdump ( exact cmdl: tcpdump -n -vv -x -i eth1 'port 8881' ) and can't be seen with netcat ( exact cmdl: nc -u localhost 8881 ). This question might not relate directly to the topic of this forum but as I suspect that there can be a flow in the code ( which is in Qt ) i by the end decided to place it here. The code of the class relating to sending datagrams looks like this
    header

    #ifndef TCP_SRC_HPP
    #define TCP_SRC_HPP
    
    #include <QScopedPointer>
    #include <QUdpSocket>
    #include <QFile>
    #include <QTimer>
    
    #include "read_config.hpp"
    #include "process_data.hpp"
    
    class TcpSrc: public QObject {
        Q_OBJECT
    public:
        TcpSrc( const QObject *parent = 0 );
        ~TcpSrc();
    
        const QScopedPointer< QUdpSocket > &getUdpSocket() const;
    
        void readFromFile( QFile & );
    
        void setMsg( const QString & );
        const QString &getMsg() const;
    
    
    signals:
    //    void directoryChanged();
        void fileChanged( QFile & );
        void fileWasNotChanged( QFile & );
    
    private slots:
    //    void sessionOpened();
        void parseSrc( QFile & );
        void checkFileChanges( QFile & );
        void checkDirectoryChanges();
    
    private:
        void startSending();
        void filMsgToSnd( const QString &, quint16 );
    
        QScopedPointer< QUdpSocket > udpSocket;
    
        ReadConfig *confFile;
        QString msg;
        ProcessData *processData;
        QTimer readTimer;
    
    };
    
    #endif // TCSP_CLIENT_HPP
    

    src:

    #include <cstdint>
    
    #include <QDir>
    #include <QFile>
    #include <QFileInfo>
    #include <QDataStream>
    #include <QDateTime>
    #include <QHostAddress>
    #include <QChar>
    #include <QTimer>
    
    #include "tcp_src.hpp"
    
    TcpSrc::TcpSrc( const QObject *parent )
        : udpSocket( new QUdpSocket( this ) ) {
    
        processData = new ProcessData();
        confFile = new ReadConfig();
    
        connect( &readTimer, &QTimer::timeout, this, &TcpSrc::checkDirectoryChanges );
        connect( this, SIGNAL( fileChanged( QFile & ) ), this, SLOT( checkFileChanges( QFile & ) ) );
        connect( this, SIGNAL( fileWasNotChanged( QFile & ) ), this, SLOT( parseSrc( QFile & ) ) );
        readTimer.start(1000);
    }
    
    void TcpSrc::checkDirectoryChanges() {
        QDir crntDir( confFile->getSrcFilePath() );
        if ( !crntDir.exists() )
            qDebug() << "Couldn't open directory";
    
        if ( !crntDir.isEmpty() ) {
            for ( auto fileN : crntDir.entryList() ) {
                QString fileFullName = crntDir.absoluteFilePath( fileN );
    
                if ( ( fileFullName.contains( QString( "/." ) ) ) || fileFullName.contains( QString( "/.." ) ) ||
                     ( fileFullName.contains( QString( "\\." ) ) ) || fileFullName.contains( QString( "\\.." ) ) )
                    continue;
    
                QFile file( fileFullName );
                    emit fileChanged( file );
            }
        } else
            qDebug() << confFile->getSrcFilePath() << " is empty";
    }
    
    void TcpSrc::checkFileChanges( QFile &file ) {
        QFileInfo fi( file );
    
        if ( fi.lastModified() > QDateTime::currentDateTime().addSecs( -1 ) ) {
            QTimer timer;
            timer.setInterval( 1000 );
            connect( &timer, &QTimer::timeout, this, &TcpSrc::checkDirectoryChanges );
        } else {
            emit fileWasNotChanged( file );
        }
    }
    
    const QScopedPointer< QUdpSocket > &TcpSrc::getUdpSocket() const {
        return udpSocket;
    }
    
    void TcpSrc::parseSrc( QFile &file ) {
        QDir dir( confFile->getSrcFilePath() );
        QString fileName;
        if ( !file.open( QIODevice::ReadOnly ) )
            qDebug() << "Couldn't open the file";
    
        processData->setCheckSum( file, processData->defineCheckSumAlg( confFile->getCheckSumAlg() ) );
        QFileInfo fi( file );
        if ( sizeof( ( fi.fileName() ).toStdString().c_str() ) <= FILE_NAME_SIZE ) {
            fileName.insert( 0, fi.fileName() );
            size_t size_diff = FILE_NAME_SIZE - ( fi.fileName() ).size();
    
            for ( size_t i = 0; i < size_diff; ++i ) {
                fileName.prepend( '0' );
            }
        } else {
            fileName.insert( 0, ( fi.fileName() ).constData(), FILE_NAME_SIZE );
            qDebug() << "Size of the file name exceeds allocated limits";   // write it to log
        }
        quint16 msgN = 1; // chunk pos in seq of chunks sent
        if ( confFile->getDatagramSize() <= DATAGRAM_HEADER ) {
            filMsgToSnd( fileName, msgN );
            processData->setSndMsgsSq( getMsg() );
        } else {
            // actual message size | without header
            size_t chunk_size = confFile->getDatagramSize() - DATAGRAM_HEADER;
    
            char *temp;  // chunk without header
    
            // actual size of the message inside datagram
            int size = chunk_size;
    
            QDataStream in( &file );
            while( !file.atEnd() ) {
                if ( msgN <= file.size() / chunk_size ) {
                    temp = ( char * )calloc( chunk_size + 1, sizeof( char ) );
    
                    size = chunk_size;
                } else {
                    temp = ( char * )calloc( ( file.size() % chunk_size ) + 1, sizeof( char ) );
    
                    size = file.size() % chunk_size;
                }
    
                int dataRead = 0;
                if ( ( dataRead = in.readRawData( temp, size ) ) < 0 )
                    qDebug() << "No datum were read";
    
                qDebug() << "dataRead " << dataRead;
                temp[ dataRead + 1 ] = '\0';
    
                filMsgToSnd( fileName, msgN );
                setMsg( QString( temp ) );
    
                processData->setSndMsgsSq( getMsg() );
                ++msgN;    // represent chunk pos in seq
                free( temp );
                temp = NULL;
    
                msg.clear();
            }
        }
        file.close();
    
        if ( confFile->getDatagramSize() > DATAGRAM_HEADER ) {
            if ( !dir.remove( fi.fileName()) )
                qDebug() << fi.fileName() << " was not removed";
        }
    
        startSending();
    
        dir.refresh();
    }
    
    const QString &TcpSrc::getMsg() const {
        return msg;
    }
    
    void TcpSrc::setMsg( const QString &msg ) {
        if ( !msg.isNull() )
            this->msg.append( msg );
        else {
            qDebug() << "Message was empty";
            // Add error check
        }
    }
    
    void TcpSrc::startSending() {
        udpSocket.data()->connectToHost( confFile->getIpAddress(), confFile->getDstPortNumber(), QIODevice::WriteOnly );
    
    // added for debugging | write it to log
        if ( QAbstractSocket::UnconnectedState == udpSocket.data()->state() )
            qDebug() << "UnconnectedState";
        else if ( QAbstractSocket::HostLookupState == udpSocket.data()->state() )
            qDebug() << "HostLookupState";
        else if ( QAbstractSocket::ConnectingState == udpSocket.data()->state() )
            qDebug() << "ConnectingState";
        else if ( QAbstractSocket::BoundState == udpSocket.data()->state() )
            qDebug() << "BoundState";
        else if ( QAbstractSocket::ClosingState == udpSocket.data()->state() )
            qDebug() << "ClosingState";
        else if ( QAbstractSocket::ListeningState == udpSocket.data()->state() )
            qDebug() << "ListeningState";
        else if ( QAbstractSocket::ConnectedState == udpSocket.data()->state() )
            qDebug() << "ConnectedState";
    // ================================================================================ //
        quint64 dataWritten = 0;
        for ( auto sndMsg: processData->getSndMsgsSq() ) {
            for ( size_t i = 0; i < confFile->getNumOfRpSnd(); ++i ) {
                dataWritten = udpSocket.data()->writeDatagram( sndMsg.toStdString().c_str(), qstrlen( sndMsg.toStdString().c_str() ),
                                                               QHostAddress( confFile->getIpAddress() ), confFile->getDstPortNumber() );
            }
        }
        udpSocket.data()->disconnectFromHost();
    }
    
    void TcpSrc::filMsgToSnd( const QString &fName, quint16 msgN ) {
        setMsg( fName );
        setMsg( QString( processData->intToStr( msgN ) ) );
        processData->setUuid();
        setMsg( QString( processData->getUuid() ) );
        setMsg( QString( processData->getCheckSum() ) );
    }
    
    TcpSrc::~TcpSrc() {}
    
    

    port and ip adress are predefined in configureation file. Which contain e.g. the following info ip:127.0.0.1 dst_port:8881, i.e. udpSocket in QScopedPointer< QUdpSocket > udpSocket is 8881
    and confFile->getIpAddress() returns IP address of the host to which it is intended to send datagrams ( 127.0.0.1 ).

    Will be very grateful for any help
    Thank you in advance


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but why are you using a QUdpSocket in a class named TcpSrc ? Shouldn't it be QTcpSocket ?



  • @SGaist Not a silly at alL )) I started from the example on Tcp server from network-exaples and just left the name as it was. Of course it can lead to misunderstanding, which is not a good practice, i understand.



  • I could solve this problem, not exactly myself though. The thing was that the server to which i was trying to send datagrams
    form this client was on a virtual machine and i had wrong network settings there.


  • Lifetime Qt Champion

    Great !

    Glad you found out and thanks for sharing !


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.