QTcpSocket: Mit IRC Server kommunizieren



  • Hallo,

    ich habe ein Problem mit QTcpSocket! Ich habe eine Klasse connection , diese hat einen QTcpSocket und innerhalb dieser Klasse versuche ich mit einem IRC-Server zu kommunizieren. Das Problem dabei ist, dass der Server nachdem er mir das PING sendet, und ich ihm daraufhin das PONG zurücksende nicht mehr antwortet und ich versteh einfach nicht warum. Ich habe darauf aufgepasst, dass meine Messages, die ich dem Server zuschicke mit CRLF aufhören und ich habe einen Signal/Slot Mechanismus fürs PING/PONG eingebaut.

    Hier ein paar Zeilen Code:

    #include "connection.hpp"
    #include <sstream>
    
    connection::connection(const server_info& inf, QObject* parent)
        : QObject{parent}, info{inf}{
    
        connect(socket, &QTcpSocket::connected, this, &connection::register_to_server);
        connect(socket, &QTcpSocket::readyRead, this, &connection::read_line);
    
        connect(this, &connection::on_ping, [this](const network::irc_message& message){
            auto cmd = message.command;
            cmd.name = "PONG";
            send(std::move(cmd));
        });
    
        socket->connectToHost(info.server, info.port);
    }
    
    void connection::read_line(){
        network::irc_message message;
        QString raw_message = socket->readLine();
        raw_message.replace("\r\n", "");
        std::stringstream stream(raw_message.toStdString());
    
        message.parse(stream);
        process_message(message);
    }
    
    void connection::process_message(const network::irc_message& message){
        emit on_receive(message);
    
        if(message.is_command()){
            emit on_command(message.command);
    
            if(message.command.name == "PING")          emit on_ping(message);
            else if(message.command.name == "PRIVMSG")  emit on_privmsg(message);
            else if(message.command.name == "NOTICE")   emit on_notice(message);
    ...
        }
    
        else if(message.is_numeric_reply())
            emit on_numeric_reply(message.reply);
    }
    
    void connection::register_to_server(){
        send({"PASS", {"none"}});
        send({"USER", {"_", "_", "_", ":Unknown"}});
        send({"NICK", {info.nick.toStdString()}});
    }
    

    Im Konstruktor setze ich die Signals/Slots und konnektiere zu dem Server. Das klappt auch, register_to_server() wird aufgerufen und es wird mittels PASS, USER und NICK an den Server registriert. Wenn ich das getan habe, wird readyRead() zum ersten Mal ausgelöst und weiter gehts mit read_line(). Die erste Message, die der Server mir zurücksendet, ist ein NOTICE, ein paar Sekunden später trifft das PING ein. Mittels dem Debugger habe ich überprüft, dass on_ping() tatsächlich ausgelöst wird und qDebug() << QString(cmd.string().c_str()); gibt mir auch tatsächlich genau "PONG :1234\r\n" zurück (siehe Zeilen 12 bis 14).

    Jetzt, nach dem PONG, kommt nichts mehr. Warum kommt nichts mehr?
    Ums nochmal zusammenzufassen:

    • [] Ein paar Numeric Replies empfangen

    An der Klasse irc_message kann es nicht liegen. Ich habe bereits einen Bot in der Konsolenanwendung geschrieben, wobei ich genau diese Klasse benutzt habe und funktioniert tadellos. Bei meinem Bot bin ich auch genau so vorgegangen, wie es in der oben genannten Liste steht und funktioniert. Kann es sein, dass es an readyRead() liegt? Vielleicht irgendein Grund, warum es nur zweimal ausgelöst wird?

    Ich hoffe sehr, dass mir jemand helfen kann, da ich nicht mehr weiter weiß.



  • Ich habe jetzt herausgefunden, dass kurz nach dem PING das Signal disconnected() vom Socket ausgelöst wird. Bin aber noch am Grübeln, warum der sich auf einmal disconnected().



  • Ein...

    if(socket->bytesAvailable())
            emit socket->readyRead();
    

    ...am Ende der read_line() Funktion hat das Problem nun gelöst.



  • Du bist dir aber darüber im Klaren, dass das ein ganz übler Hack ist und weit entfernt von einer ordentlichen Problemlösung?


Anmelden zum Antworten