Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

how do i know QTcpSocket signal bytesWritten( qint64 bytes ) stand for which when serveral object called write(..) function with same bytes to write?



  • i have code like this:

    class CTcpSocket : public QTcpSocket
    {
    Q_OBJECT
    public:
    static CTcpSocket *GetSelf( )
    {
    if( nullptr != m_pSocket ) return m_pSocket;

    	m_pSocket = new CTcpSocket;
    	return m_pSocket;
    }
    

    public slots:
    void OnBytesWritten( qint64 bytes )
    {
    //
    // when bytesWritten signal will emitted, will call this slot function,
    // but don't know which object called write(...) function lead bytesWritten signal emit.
    //
    }

    private:
    CTcpSocket( )
    {
    //
    // do init things,
    // this not the point we care here, forget them
    //
    connect( this, &CTcpSocket::bytesWritten, this, &CTcpSocket::OnBytesWritten );
    }

    private:
    static CTcpSocket *m_pSocket;
    };

    class CA
    {
    public:
    CA( const QString &name )
    {
    m_name.clear( );
    m_name += name;
    }

    void SendName( )
    {
    	CTcpSocket::GetSelf( )->write( m_name );
    }
    

    private:
    QByteArray m_name;
    };


    {
    QApplication a( argc, argv );

    CA a_001( QString( "hello_001" ) );
    CA a_002( QString( "hello_002" ) );
    
    
    //
    // two object has the same bytes to write,
    // when OnBytesWritten( qint64 ) called, 
    // how do i know which object(a_001 or a_002) lead the slot call ?
    //~~strikethrough text~~
    a_001.SendName( );
    a_002.SendName( );
    
    
    
    
    
    return a.exec( );	
    

    }

    two object has the same bytes to write,
    when OnBytesWritten( qint64 ) called,
    how do i know which object(a_001 or a_002) lead the slot call ?



  • @HelloQt
    You cannot know in slot OnBytesWritten which object invoked your SendName(). In SendName() itself you know it is this which is doing the writing.



  • @JonB so, when we post serveral io on a socket,
    do you know how to get the object who has posted io when bytesWritten( qint64) called ?



  • @HelloQt
    No I do not, any more than if you had two objects writing to the same file I would not know which one happened to issue a write().

    If it comes to that, I'm not sure that https://doc.qt.io/qt-5/qiodevice.html#bytesWritten gets called once per your write()s anyway. It can accumulate bytes to write from separate calls, or split bytes to write into multiple packets, so the whole thing you want to detect may not make sense.

    I don't know why you're trying to do this anyway, doesn't sound good, it would be better if you can avoid needing to know this in the slot. Maybe you can move your logic into SendName() itself, possibly you could call https://doc.qt.io/qt-5/qabstractsocket.html#waitForBytesWritten there, but note that is not good if Windows plus may not be good for efficiency....



  • @JonB said in how do i know QTcpSocket signal bytesWritten( qint64 bytes ) stand for which when serveral object called write(..) function with same bytes to write?:

    @HelloQt
    You cannot know in slot OnBytesWritten which object invoked your SendName(). In SendName() itself you know it is this which is doing the writing.

    i now have a stupid way to get the object who has posted io on socket,
    i construct special bytes to write among every io, so when bytesWritten( qint64 bytes ) called, i got different argument with slot bytesWritten( qint64 bytes ), then i knew which object has posted this io,
    but i want a smart implementation to solve this problem.



  • @JonB said in how do i know QTcpSocket signal bytesWritten( qint64 bytes ) stand for which when serveral object called write(..) function with same bytes to write?:

    It can accumulate bytes to write from separate calls, or split bytes to write into multiple packets, so the whole thing you want to detect may not make sense.
    I don't know why you're trying to do this anyway, it would be better if you can avoid needing to know this in the slot. Maybe you can move your logic into SendName() itself, possibly you could call https://doc.qt.io/qt-5/qabstractsocket.html#waitForBytesWritten there, but note that is not good if Windows plus may not be good for efficiency....

    with your reply tips:

    {
    " It can accumulate bytes to write from separate calls, or split bytes to write into multiple packets, so the whole thing you want to detect may not make sense."
    }
    yes, if things so complicate, all my code about this problem become no sense, sadness story.

    {
    "I don't know why you're trying to do this anyway, doesn't sound good, it would be better if you can avoid needing to know this in the slot. "
    }
    the reason i want to do is:
    when one object which constructed on heap finished it's io,
    i release the object



  • @HelloQt

    the reason i want to do is:
    when one object which constructed on heap finished it's io,
    i release the object

    I don't know exactly what you're trying to achieve/your code does, but this just doesn't sound right at all.... 'Nuff said. [Plus, your example allocates CAs on the stack not the heap. Plus, in your code you don't need to wait till bytes have been written to TCP socket, you might as well put in the logic for any "disposal" of a CA immediately after the call to SendName(), which would avoid this whole nonsense?]

    BTW, if I really, really needed to do what you say, I would expand your CTcpSocket wrapper class and/or derive from QTcpSocket so that it holds a reference, "lastWriter", to one of your CA objects. And change SendName( ) so that its this gets stored as the "lastWriter". Then you could access that in the slot. It's not ideal, and suffers from same problems if packets are accumulated, but sounds closest to what you want....



  • @JonB Yes, thank you very much, i would think your advice carefully


  • Lifetime Qt Champion

    Hi,

    First thing, why are you using the singleton pattern here ?
    Then, why are you subclassing QTcpSocket ?

    If you want to use only one socket then just instantiate one and use it. If you want to have a class that does some stuff and then send it through the socket, then design it so.



  • @SGaist
    1:
    { "First thing, why are you using the singleton pattern here ?" }
    using singleton pattern reason is: i need just only one socket object in my application

    {"Then, why are you subclassing QTcpSocket ?"}
    the reason is : for convenience of initializ the object, may be you think this ridiculous, LOL.

    but those not the point we care about.

    let's make the question more common:

    if you have many objects,
    and each object post an i/o on the socket( here means you will call socket.write(...) function ),

    all posted i/o in asynchronous way,

    you want delete those object who posted i/o finished ( for save memory ),

    so , you need to be notified when the socket done the i/o,

    how to get this notify ?

    if you think about to use bytesWritten( qint64 bytes ) signal,
    then you meet the trouble i asked in this topic.

    or you have a better way to get this notify,
    please tell me, thank you



  • @HelloQt said in how do i know QTcpSocket signal bytesWritten( qint64 bytes ) stand for which when serveral object called write(..) function with same bytes to write?:

    if you have many objects,
    and each object post a io on the socket( here means you will call socket.write(...) function ),
    all posted io in asynchronous way,
    you want delete those object who posted io finished ( for save memory ),
    so , you need to be notified when the socket done the io,
    how to get this notify ?

    As I said earlier (unless @SGaist says otherwise), in your case you can delete those objects once they have called the socket.write(), you do not need to wait till a signal for the bytes have been written to be able to delete the sending object, your socket is still in existence regardless.


  • Lifetime Qt Champion

    In that case you should rather abstract that part away. If these object don't need to survive long terms, why not just have a queue of data to send ? That way you pass around a controller class to which your various object enqueues these data and the controller will write to the socket.



  • @JonB said in how do i know QTcpSocket signal bytesWritten( qint64 bytes ) stand for which when serveral object called write(..) function with same bytes to write?:

    @HelloQt said in how do i know QTcpSocket signal bytesWritten( qint64 bytes ) stand for which when serveral object called write(..) function with same bytes to write?:

    if you have many objects,
    and each object post a io on the socket( here means you will call socket.write(...) function ),
    all posted io in asynchronous way,
    you want delete those object who posted io finished ( for save memory ),
    so , you need to be notified when the socket done the io,
    how to get this notify ?

    As I said earlier (unless @SGaist says otherwise), in your case you can delete those objects once they have called the socket.write(), you do not need to wait till a signal for the bytes have been written to be able to delete the sending object, your socket is still in existence regardless.

    I have thought over your advice, and have done a test.
    finally, yes, you are right.

    I was misled by the windows iocp thinking-mode.
    I thought signal bytesWritten( qint64 bytes ) of QTcpSocket like the windows iocp notify.
    Now I know I was totally wrong.

    According to the test result,
    things run like what you have said, QTcpSocket can accumulate bytes to write from separate calls,
    or split bytes to write into multiple packets, this is the truth.

    ok, problem solved.
    Thanks awfully for your help.

    (image is the test result:0_1553247170639_example result.png )

    test code :
    system, windows 10 64bit
    qt, version 5.6.3
    compiler, visual c++ 2015
    [0_1553247303256_Trainning_03_21.zip](Uploading 100%)



  • @HelloQt sorry, i have no privilege to upload the test code.


Log in to reply