QTcpSocket in a console app



  • I'm somewhat new to Qt, having only had it for a week and devoting hours of self-learning/research to it. I'm trying to produce a console app that utilizes QTcpSocket and some general use Qt classes to try my hand at console app event handling. I started by attempting to produce a client program for an old peer-to-peer protocol called Hotline -- that is, an incomplete one that simply does a handshake and gets confirmation then disconnects, which shouldn't require multiple threads I think. It does this by writing 'TRTPHOTL' and the 16-bit values 1 and 2 to the socket. If successful, the server is to respond with 'TRTP' and two 16-bit values of 0, which I'd usually retrieve by reading the socket buffer. I come from C# but have prior knowledge in C++ as well.

    What follows is my attempt at what I described above using C++ and Qt 4.8.2, and the .pro file as well for convenience. Following that I have posted the sample I had written and tested successfully in C#. Before suggesting I stick with C# though, I will say I prefer C++ because of its advantages over C#, but until finding out about Qt I hadn't used it due to lack of a suitable toolkit.

    This doesn't seem to do as I intended. It compiles, but the output confuses me. On Win32 it has a chance to output the input as I code it to, but on Linux, nothing. The error below is given on both platforms:

    @QObject::connect: Cannot connect (null)::destroyed() to QHostInfoLookupManager::waitForThreadPoolDone()@

    hlclient.cpp:
    @#include <QCoreApplication>
    #include <QByteArray>
    #include <QTcpSocket>
    #include <QTextStream>

    int main()
    {
    QTcpSocket * sock = new QTcpSocket();
    QTextStream out(stdout);
    QByteArray hi("TRTPHOTL\x00\x01\x00\x02"); // TRTPHOTL (int16)1 (int16)2
    sock->connectToHost("localhost", 5500);
    if (sock->waitForConnected(10000))
    {
    sock->write(hi.data());
    if (sock->waitForBytesWritten(10000))
    {
    out << "Wrote " << hi.data() << "\n";
    hi.clear();
    if (sock->waitForReadyRead(10000))
    {
    hi = sock->readAll();
    out << "Read " << hi.data() << "\n";
    }
    }
    sock->disconnectFromHost();
    }
    sock->close();
    delete sock;
    }
    @

    hlclient.pro:
    @TEMPLATE = app
    TARGET =
    DEPENDPATH += .
    INCLUDEPATH += .
    CONFIG += console
    QT += network
    SOURCES += hlclient.cpp@

    HLClient.cs:
    @using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;

    static class HLClient
    {
    static void Main(string[] args)
    {
    TcpClient sock = new TcpClient("localhost", 5500);
    byte[] data = {0x54, 0x52, 0x54, 0x50, 0x48, 0x4f, 0x54, 0x4c, 0x00, 0x01,
    0x00, 0x02};
    NetworkStream stream = sock.GetStream();
    stream.Write(data, 0, data.Length);
    Console.WriteLine("Sent stuff");
    data = new byte[8];
    string resp = string.Empty;
    int bytes = stream.Read(data, 0, data.Length);
    resp = Encoding.ASCII.GetString(data, 0, bytes);
    Console.WriteLine("Received {0}", resp);
    stream.Close();
    sock.Close();
    }
    }@



  • First of all,

    @
    QByteArray hi("TRTPHOTL\x00\x01\x00\x02"); // TRTPHOTL (int16)1 (int16)2
    @
    is wrong. which equals
    @
    QByteArray hi("TRTPHOTL"); // TRTPHOTL (int16)1 (int16)2
    @

    what you need is
    @
    QByteArray hi("TRTPHOTL\x00\x01\x00\x02", 12); // TRTPHOTL (int16)1 (int16)2
    @

    Second, You need a QCoreApplication instance

    so, change
    @
    int main()
    {
    @
    to
    @
    int main(int argc, char** argv)
    {
    QCoreApplication app(argc, argv);
    @



  • Alright did that. However my "return a.exec();" statement (declared QCoreApplication as 'a') now makes my app sit there and do nothing.



  • Learn about asyncronic programming. Really. Instead of using the waitFor... methods, just use the signal/slot based ones and react to the incommig data. Don't try to spin your own eventloop or something like that, just use Qt's one.



  • Please comment the last line // delete sock; and try again and see what you get.



  • Alright, well I restructured my program and derived QTcpSocket as to implement signals. However, though I overrode connected(), disconnected(), and readyRead(), I am unsure how to connect them, as QCoreApplication's slots aren't really suitable.



  • It will be more clear for beginners when they understand the basics of socket programming , plz follow the link .. http://csharp.net-informations.com/communications/csharp-socket-programming.htm it will provide the basics.

    vayne.


Log in to reply
 

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