Results 1 to 14 of 14

Thread: How do I use QTcpSocket properly ?

  1. #1
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Unhappy How do I use QTcpSocket properly ?

    bool CMsgClient::SendPacket(const void *buf, size_t len)
    {
    QTcpSocket tcpSocket;
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (const char*)buf;
    out.device()->seek(0);

    tcpSocket.write(block, len);

    return true;
    }

    I'm trying to send a data from buf, but when I debug it, the block byte array don't have the similar data as buf. Can anybody advise me on how to use QTcpSocket ?

  2. #2
    Join Date
    Jan 2006
    Location
    Alingsås, Sweden
    Posts
    437
    Thanks
    3
    Thanked 39 Times in 39 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    Two things:

    #1 You allocate the socket on the heap, and then return from your method before it has finished sending. You need to wait for it before exiting your method.

    #2 Why don't you use the qint64 write ( const char * data, qint64 maxSize ) method directly, and skip the buffering.

  3. #3
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: How do I use QTcpSocket properly ?

    Ok, this is what I change :

    bool CMsgClient::SendPacket(const void *buf, size_t len)
    {
    QTcpSocket tcpSocket;
    tcpSocket.write((const char*)buf, len);
    }

    I send the packet to localhost 127.0.0.1,
    but, still I don't see any packet sent to the localhost.
    Why is that ?

    Do I need to write specific code to send the 'buf' ?
    Is there anything that I should pay attention for ?
    Does it depends on the endpoint of the network ?

    Sorry, I'm a newbie in Qt, I'm just surprised by the small amount of code that I need to write to send data through TCP connection.

    Please help.

  4. #4
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    Quote Originally Posted by mnemonic_fx View Post
    Ok, this is what I change :

    bool CMsgClient::SendPacket(const void *buf, size_t len)
    {
    QTcpSocket tcpSocket;
    tcpSocket.write((const char*)buf, len);
    }

    I send the packet to localhost 127.0.0.1,
    but, still I don't see any packet sent to the localhost.
    Why is that ?
    Are you sure the packet will be send to localhost? It really shouldn't if you are using this code...
    • As e8johan said, heap allocation is seldom used in network programming because the socket is most likely to be destroyed before completing its task
    • your socket doesn't seem to be connected to any host... QAbstractSocket::connectToHost()
    • If you really want to allocate you socket on heap you should give him some more time (potientially freezing GUI but that's another issue...) :
    Qt Code:
    1. sock.connectToHost("127.0.0.1", 0);
    2. sock.waitForConnected();
    3. sock.write((const char*)buf, len);
    4. sock.waitForBytesWritten();
    To copy to clipboard, switch view to plain text mode 
    Note : Heap allocation will be IMPOSSIBLE if your data is too long and needs to be split into several packets by QTcpSocket, internally. In this case only the first packet (or maybe the two first if you're lucky) will be sent...
    Current Qt projects : QCodeEdit, RotiDeCode

  5. #5
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: How do I use QTcpSocket properly ?

    Sorry, I don't write the complete code,
    I connect to a host from a class that inherits from QThread,
    and I run a server at port 9060.

    something like this :

    Qt Code:
    1. CMsgSession::run()
    2. {
    3. while (!workerQuitFlag) {
    4. const int Timeout = 5 * 1000;
    5.  
    6. QTcpSocket tcpSocket;
    7. tcpSocket.connectToHost(serverName, serverPort);
    8.  
    9. if (!tcpSocket.waitForConnected(Timeout)) {
    10. emit error(tcpSocket.error(), tcpSocket.errorString());
    11. return;
    12. }
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 

    I was expecting that the connection is still established while the tread is running, so I write the data from another class, which is called after the thread is executed.

  6. #6
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    It looks like you're getting something wrong : QTcpSocket is a class. You can instantiate objects in two ways : either on heap (as you're apparently doing) so that they get deleted when the local scope is left or dynamically (through "new" operator) so that they remain until explicit deletion. As far as I understand your design you'll need the second way. Indeed, creating a new QTcpSocket in a function after having established a connection with *another* QTcpSocket won't lead anywhere... On the contrary you should add a member to your thread class ("QTcpSocket *pSocket;", for instance), initialize it properly in the run() function and then send data through it in your sendPacket() function. Another thing worth being said is that QTcpSocket internally manages "packets". i.e. it splits data if necessary and sends packets one by one in the right order...
    Current Qt projects : QCodeEdit, RotiDeCode

  7. #7
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: How do I use QTcpSocket properly ?

    Quote Originally Posted by fullmetalcoder View Post
    Indeed, creating a new QTcpSocket in a function after having established a connection with *another* QTcpSocket won't lead anywhere... On the contrary you should add a member to your thread class ("QTcpSocket *pSocket;", for instance), initialize it properly in the run() function and then send data through it in your sendPacket() function.
    I'm very sorry again, because I don't write my complete code on this question.
    I already done what you have said, but I still get a -1 return from
    qint64 write ( const char * data, qint64 maxSize ) method.

    I initialized my socket at CMsgSession : public QThread, and I send the packet from CMsgClient class. Once I use your code :

    Qt Code:
    1. sock.connectToHost("127.0.0.1", 9060);
    2. sock.waitForConnected();
    3. sock.write((const char*)buf, len);
    4. sock.waitForBytesWritten();
    To copy to clipboard, switch view to plain text mode 

    I could send the data, but suddenly my local server says that the client close the socket..

    What when wrong ?

    Is there a problem with my server ?

  8. #8
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: How do I use QTcpSocket properly ?

    Ok, I understand my previous problem, now I got this error when I access write function from another class :

    The program breaks at :

    private:
    Q_DECLARE_PRIVATE(QIODevice)
    Q_DISABLE_COPY(QIODevice)

    I think I need to inherit the class CMsgClient which references the function QTcpSocket CMsgSession::tcpSocket->write(..., ....) from QObject.
    Is that true ?
    Is there any other way ?

    Do I need to inherit from QObject, everytime I use Qt class ?

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    Quote Originally Posted by mnemonic_fx View Post
    Ok, I understand my previous problem, now I got this error when I access write function from another class :
    Could you post the exact error message?

    Quote Originally Posted by mnemonic_fx View Post
    Do I need to inherit from QObject, everytime I use Qt class ?
    No, you don't. Otherwise you wouldn't be able to use Qt classes in main(), not mentioning that some Qt classes aren't derived from QObject.

  10. #10
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    Quote Originally Posted by mnemonic_fx View Post
    I initialized my socket at CMsgSession : public QThread, and I send the packet from CMsgClient class. Once I use your code :

    Qt Code:
    1. sock.connectToHost("127.0.0.1", 9060);
    2. sock.waitForConnected();
    3. sock.write((const char*)buf, len);
    4. sock.waitForBytesWritten();
    To copy to clipboard, switch view to plain text mode 
    I could send the data, but suddenly my local server says that the client close the socket..

    What when wrong ?

    Is there a problem with my server ?
    Nop... If that's really the code you're using (not talking about completeness here just exactitude...) Then the connection must close as soon as the execution leaves the scope where your socket is instantiated (loop, function, whatever) because you don't use dynamic allocation but heap allocation... Thus the socket object is destroyed and stops communicating with your server... I think you should read some more about OOP and C++...
    Current Qt projects : QCodeEdit, RotiDeCode

  11. #11
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: How do I use QTcpSocket properly ?

    Quote Originally Posted by fullmetalcoder View Post
    Nop... If that's really the code you're using (not talking about completeness here just exactitude...) Then the connection must close as soon as the execution leaves the scope where your socket is instantiated (loop, function, whatever) because you don't use dynamic allocation but heap allocation... Thus the socket object is destroyed and stops communicating with your server... I think you should read some more about OOP and C++...
    When I call the function like this : (session is a pointer to class object)

    Qt Code:
    1. session->tcpSocket.write((const char*)buf,len);
    2. session->tcpSocket.waitForBytesWritten();
    To copy to clipboard, switch view to plain text mode 

    I get this error :

    Unhandled exception at 0x670afb8a (QtCored4.dll) in MyProgram.exe: 0xC0000005: Access violation reading location 0xcdcdcdd9.

    and it's break at this location :

    Qt Code:
    1. private:
    2. -> Q_DECLARE_PRIVATE(QIODevice)
    3. Q_DISABLE_COPY(QIODevice)
    To copy to clipboard, switch view to plain text mode 

    I access the tcpSocket object that was created in a running thread.
    If I want to maintain the connection what should I do ?
    create a static object ?


    By the way isn't heap allocation & dynamic allocation is the same thing, just with different terms ?

    I read this on a book, chapter 20.3 of "An Introduction to Design Patterns in C++ with Qt" :

    The heap or free storage (dynamic storage): Objects created via new are examples.
    The lifetime of a heap object is determined entirely by the use of new and delete.
    In general, the allocation and freeing of heap objects should be in carefully encapsulated classes.
    And I read this on a book, chapter 3 of "Memory Management, Algorithms and Implementations in C-C++" :
    Heap memory allocation, also known as dynamic memory allocation
    (DMA), consists of requesting memory while an application is running
    from a repository known as the heap.

  12. #12
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    1. Generally speaking accessing class members directly is wrong. Instead you should provide wrapper functions/slots/whatever to handle that
    2. Sounds like your QTcpSocket object is an object and not a pointer. This is also considered as bad design because it is NOT a type which can be copied (noticed the Q_DISABLE_COPY() macro ?) just like basic types (int, QString, QPixmap QList<>, ... for instance) which implies that in most cases, and especially when using such objects outside of their creation scope, they should be created through new and accessed via pointers...
    3. There seems to be quite a misunderstanding about semantics... I used to to think that "heap allocation" referred to objects created as objects (i.e. without "new" operator) which were automatically deleted when the program leaved the creation scope whereas "dynamic allocation" referred to process of creating objects via "new" and deleting them manually with "delete". I might have been misleaded as far as names are concerned (and I shall investigate this) but my remarks still stand in your case : use pointers when dealing with network objects!

    Hope this helps.
    Current Qt projects : QCodeEdit, RotiDeCode

  13. The following user says thank you to fullmetalcoder for this useful post:

    mnemonic_fx (29th March 2007)

  14. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I use QTcpSocket properly ?

    Quote Originally Posted by mnemonic_fx View Post
    session->tcpSocket.write((const char*)buf,len);
    How do you initialize buf and len?

    Quote Originally Posted by mnemonic_fx View Post
    and it's break at this location : (...)
    Could we see the backtrace?

  15. #14
    Join Date
    Mar 2007
    Posts
    28
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: How do I use QTcpSocket properly ?

    Ok, I think I understand about dynamic allocation and using pointers, I try to use that, but still.. it doesn't solve my problem.

    I declare CMsgSession *session on CMsgClient private member.
    I write this on the constructor :

    Qt Code:
    1. CMsgClient::CMsgClient()
    2. {
    3. session = new CMsgSession();
    4. }
    To copy to clipboard, switch view to plain text mode 

    And I declare QTcpSocket *tcpSocket on CMsgSession public member, I write this on the constructor :

    Qt Code:
    1. CMsgSession::CMsgSession(QObject *parent) : QThread(parent), workerQuitFlag(false)
    2. {
    3. tcpSocket = new QTcpSocket();
    4. }
    To copy to clipboard, switch view to plain text mode 

    and I access the tcpSocket like this :

    session->tcpSocket->write(buf, len);

    it causes access violation, it's getting more confusing,
    but thanks anyway..

Similar Threads

  1. Tell QTcpSocket which interface to use
    By rianquinn in forum Qt Programming
    Replies: 7
    Last Post: 23rd December 2010, 17:28
  2. problem with QTcpSocket
    By SuperSonik in forum Qt Programming
    Replies: 8
    Last Post: 31st January 2007, 16:00
  3. Problems with QThread and QTcpSocket
    By cookiem in forum Qt Programming
    Replies: 6
    Last Post: 2nd November 2006, 08:25
  4. Problem with QTcpSocket and QDataStream
    By Valheru in forum Qt Programming
    Replies: 4
    Last Post: 16th September 2006, 13:08
  5. QTcpSocket disconnection problem
    By erdi in forum Qt Programming
    Replies: 4
    Last Post: 19th February 2006, 21:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.