Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTcpSocket / QTcpServer, two way communication

QTcpSocket / QTcpServer, two way communication

Scheduled Pinned Locked Moved Unsolved General and Desktop
23 Posts 3 Posters 2.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    SPlatten
    wrote on 24 Nov 2020, 18:11 last edited by SPlatten
    #1

    I am trying to sort out what I'm doing wrong...I have an application that uses QTcpServer to listen for connections and this works....Another process uses QTcpSocket to connect to the server and send a message.

    I also want to be able to send messages from the server application to the process using QTcpSocket and its this that I'm having problems with.

    When the client (process using QTcpSocket) sends a message, the server (process using QTcpServer) answers with an Acknowledge message, no problems with either of these and this works perfectly.

    I have a problem sending a message from the server to the client that isn't in response to a message already received, when I tried this using the same socket that is used to receive messages from the client, nothing is written and the result returned from write is -1.

    The server application:

    listen(QHostAddress::Any, uint16Port);
    QList<QHostAddress> lstAddresses = QNetworkInterface::allAddresses();
    QString strIP;
    for( int i=0; i<lstAddresses.size(); i++ ) {
        if ( lstAddresses[i] != QHostAddress::LocalHost
          && lstAddresses[i].toIPv4Address() ) {
            strIP = lstAddresses[i].toString();
            break;
        }
    }
    if ( strIP.isEmpty() == true ) {
        strIP = QHostAddress(QHostAddress::LocalHost).toString();
    }
    Q_ASSERT_X(isListening(), "clsSocketServer::clsSocketServer", strListenFailure.toLatin1().data());
    QObject::connect(this, &QTcpServer::newConnection, this, &clsSocketServer::newConnection);
    #if defined(DEBUG_SOCKETS)
    qdbg() << tr("Listening on: %1:%2\n")
                .arg(strIP).arg(uint16Port);
    #endif
    

    The client:

    QByteArray arybytMsg;
    QDataStream dsOut(&arybytMsg, QIODevice::WriteOnly);
    dsOut.setVersion(clsJSON::mscintQtVersion);
    //Send message to data stream
    dsOut << QJsonDocument(objJSON).toJson(QJsonDocument::Compact);
    //Write message
    qint64 int64Written = write(arybytMsg);
    qdbg() << "sendJSON: " << int64Written;
    

    Kind Regards,
    Sy

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 24 Nov 2020, 18:52 last edited by
      #2

      Hi,

      How have you implemented the socket handling server-side ?

      There's likely something wrong there as you should be able to send data back.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      S 1 Reply Last reply 24 Nov 2020, 18:57
      1
      • S SGaist
        24 Nov 2020, 18:52

        Hi,

        How have you implemented the socket handling server-side ?

        There's likely something wrong there as you should be able to send data back.

        S Offline
        S Offline
        SPlatten
        wrote on 24 Nov 2020, 18:57 last edited by
        #3

        @SGaist , I'm really not sure why I can't send, I can send an Acknowledge back and this works in response to receiving a message, but when I try to send an unsolicited message it fails.

        Kind Regards,
        Sy

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 24 Nov 2020, 19:03 last edited by
          #4

          Hence my question: how did you implement the socket handling server side ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          S 1 Reply Last reply 24 Nov 2020, 19:51
          0
          • S SGaist
            24 Nov 2020, 19:03

            Hence my question: how did you implement the socket handling server side ?

            S Offline
            S Offline
            SPlatten
            wrote on 24 Nov 2020, 19:51 last edited by SPlatten
            #5

            @SGaist , Yes, however it could probably be improved, did you see the edit of my post which has the only signal and slot I'm connecting to on the server?

            When a message is send from the server to the client, the code halts on line 127 of qsocketnotifier.h:

            return lhs.sockfd != rhs.sockfd;
            

            Kind Regards,
            Sy

            K 1 Reply Last reply 25 Nov 2020, 07:50
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 24 Nov 2020, 20:08 last edited by
              #6

              Your connect call looks fishy.

              Why are you using this twice in your connect statement ? It looks like you are connecting the signal of the base class to either the same signal in a derived class or that you have a slot of the exact same name as the signal.

              Also, why did you subclass QTcpServer ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              S 1 Reply Last reply 25 Nov 2020, 07:35
              2
              • S SGaist
                24 Nov 2020, 20:08

                Your connect call looks fishy.

                Why are you using this twice in your connect statement ? It looks like you are connecting the signal of the base class to either the same signal in a derived class or that you have a slot of the exact same name as the signal.

                Also, why did you subclass QTcpServer ?

                S Offline
                S Offline
                SPlatten
                wrote on 25 Nov 2020, 07:35 last edited by
                #7

                @SGaist , because the class is derived from QTcpServer:

                    class clsSocketServer : public QTcpServer {
                    Q_OBJECT
                
                    private:
                        static quint16 msuint16nextModulePort;
                
                        void discardClient();
                
                    protected:
                        void incomingConnection(qintptr sfd) override;
                
                    public:
                        static const QString mscstrCRLF;
                        static const quint16 mscuint16port;
                
                        explicit clsSocketServer(QObject* pParent = nullptr, quint16 uint16Port = clsSocketServer::mscuint16port);
                        ~clsSocketServer();
                
                        static quint16 uint16NextModulePort() {
                            return ++clsSocketServer::msuint16nextModulePort;
                        }
                
                    signals:
                        void newConnWithSocket(QAbstractSocket* pSocket);
                
                    public slots:
                        void acceptError(QAbstractSocket::SocketError socketError);
                        void newConnection();
                    };
                

                Kind Regards,
                Sy

                1 Reply Last reply
                0
                • S SPlatten
                  24 Nov 2020, 19:51

                  @SGaist , Yes, however it could probably be improved, did you see the edit of my post which has the only signal and slot I'm connecting to on the server?

                  When a message is send from the server to the client, the code halts on line 127 of qsocketnotifier.h:

                  return lhs.sockfd != rhs.sockfd;
                  
                  K Offline
                  K Offline
                  KroMignon
                  wrote on 25 Nov 2020, 07:50 last edited by
                  #8

                  @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                  When a message is send from the server to the client, the code halts on line 127 of qsocketnotifier.h:

                  Why do you have create a QTcpServer sub-class? Are you doing something special in incomingConnection()?
                  Most of the time there is not need to sub-class QTcpServer, by the way, I never had to do it!

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  1 Reply Last reply
                  3
                  • S Offline
                    S Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 25 Nov 2020, 07:51 last edited by
                    #9

                    So first question: why do you feel the need to subclass QTcpServer ? 95% of the time it's not necessary, always think composition over inheritance first.

                    I know that the usual way to build a Qt application is to create a class derived from QWidget/QMainWindow/QDialog and that you will have to do that for custom widgets as well, but you usually do that on a specific set of classes to then do composition with other elements unless you actively need some custom behaviour.

                    Next: why do you name a slot with exactly the same name a signal already existing in the base class ? That's actively searching for troubles. A recommandation for slot names: they usually match an action. Here for example: onNewConnection would make it clear that you are acting on a new connection.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    4
                    • S Offline
                      S Offline
                      SPlatten
                      wrote on 25 Nov 2020, 11:45 last edited by SPlatten
                      #10

                      The only purpose of this application is to act as a gateway / server between another application and the various modules it creates, I sub-classed QTcpServer because the main class and purpose is to be a server, I see no problem in doing this and its cleaner.

                      I agree with you on naming slots with a prefix of 'on' and this is exactly what I usually do.

                      Kind Regards,
                      Sy

                      K 1 Reply Last reply 25 Nov 2020, 11:54
                      0
                      • S SPlatten
                        25 Nov 2020, 11:45

                        The only purpose of this application is to act as a gateway / server between another application and the various modules it creates, I sub-classed QTcpServer because the main class and purpose is to be a server, I see no problem in doing this and its cleaner.

                        I agree with you on naming slots with a prefix of 'on' and this is exactly what I usually do.

                        K Offline
                        K Offline
                        KroMignon
                        wrote on 25 Nov 2020, 11:54 last edited by KroMignon
                        #11

                        @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                        purpose is to be a server, I see no problem in doing this and its cleaner.

                        But why did you reimplement incomingConnection() ?
                        Don't understand my wrong, it is not a judgement in any form, I only wonder why you have to do it.

                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                        S 1 Reply Last reply 25 Nov 2020, 14:56
                        0
                        • K KroMignon
                          25 Nov 2020, 11:54

                          @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                          purpose is to be a server, I see no problem in doing this and its cleaner.

                          But why did you reimplement incomingConnection() ?
                          Don't understand my wrong, it is not a judgement in any form, I only wonder why you have to do it.

                          S Offline
                          S Offline
                          SPlatten
                          wrote on 25 Nov 2020, 14:56 last edited by
                          #12

                          @KroMignon , My incomingConnection:

                          void clsSocketServer::incomingConnection(qintptr sfd) {
                              clsSocketClient* pClient = new clsSocketClient(this);
                              pClient->setSocketDescriptor(sfd);
                              addPendingConnection(pClient);   
                          }
                          

                          This part of the application is working ok, in that an external application can send messages to the server, but its sending messages from the server to the external application that is failing...all except the Acknowledge message which does make to the external application.

                          Kind Regards,
                          Sy

                          K 1 Reply Last reply 25 Nov 2020, 15:26
                          0
                          • S SPlatten
                            25 Nov 2020, 14:56

                            @KroMignon , My incomingConnection:

                            void clsSocketServer::incomingConnection(qintptr sfd) {
                                clsSocketClient* pClient = new clsSocketClient(this);
                                pClient->setSocketDescriptor(sfd);
                                addPendingConnection(pClient);   
                            }
                            

                            This part of the application is working ok, in that an external application can send messages to the server, but its sending messages from the server to the external application that is failing...all except the Acknowledge message which does make to the external application.

                            K Offline
                            K Offline
                            KroMignon
                            wrote on 25 Nov 2020, 15:26 last edited by KroMignon
                            #13

                            @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                            its sending messages from the server to the external application that is failing...all except the Acknowledge message which does make to the external application.

                            Just be sure we are talking about the same issue:
                            You have a TCP client which is connected to the TCP server, the connected client has an instance of clsSocketClient (which seems to be a subclass of QTcpSocket). Let's call the instance mClient.
                            When you do mClient.write(<something>), you've got an error.

                            Is that your problem?

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            S 1 Reply Last reply 25 Nov 2020, 16:52
                            0
                            • K KroMignon
                              25 Nov 2020, 15:26

                              @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                              its sending messages from the server to the external application that is failing...all except the Acknowledge message which does make to the external application.

                              Just be sure we are talking about the same issue:
                              You have a TCP client which is connected to the TCP server, the connected client has an instance of clsSocketClient (which seems to be a subclass of QTcpSocket). Let's call the instance mClient.
                              When you do mClient.write(<something>), you've got an error.

                              Is that your problem?

                              S Offline
                              S Offline
                              SPlatten
                              wrote on 25 Nov 2020, 16:52 last edited by SPlatten
                              #14

                              @KroMignon , there is no error sending data from the client to the server application, it regularly sends a message, a heartbeat message, which the server responds with an acknowledge. This acknowledge is also sent from the server with no error.

                              However if the server attempts to send any other message to the client, this fails and is not written, the return is -1.

                              Kind Regards,
                              Sy

                              K 1 Reply Last reply 25 Nov 2020, 17:09
                              0
                              • S SPlatten
                                25 Nov 2020, 16:52

                                @KroMignon , there is no error sending data from the client to the server application, it regularly sends a message, a heartbeat message, which the server responds with an acknowledge. This acknowledge is also sent from the server with no error.

                                However if the server attempts to send any other message to the client, this fails and is not written, the return is -1.

                                K Offline
                                K Offline
                                KroMignon
                                wrote on 25 Nov 2020, 17:09 last edited by
                                #15

                                @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                                However if the server attempts to send any other message to the client, this fails and is not written, the return is -1.

                                I don't understand this, what do you mean with "server attempts to send to client"?
                                The server TCP socket can not send/receive anything, it can only accept/reject connection requests, which are transferred to a new TCP socket. This is TCP basics, or did I misunderstood something?

                                Can you be more explicit or show a code extract?

                                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                S 1 Reply Last reply 25 Nov 2020, 17:47
                                0
                                • K KroMignon
                                  25 Nov 2020, 17:09

                                  @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                                  However if the server attempts to send any other message to the client, this fails and is not written, the return is -1.

                                  I don't understand this, what do you mean with "server attempts to send to client"?
                                  The server TCP socket can not send/receive anything, it can only accept/reject connection requests, which are transferred to a new TCP socket. This is TCP basics, or did I misunderstood something?

                                  Can you be more explicit or show a code extract?

                                  S Offline
                                  S Offline
                                  SPlatten
                                  wrote on 25 Nov 2020, 17:47 last edited by
                                  #16

                                  @KroMignon , the intention is for the server to be able to send messages to the client. However when I've tried to do this is always fails, yet a response to a message received by the server is always successful..

                                  Kind Regards,
                                  Sy

                                  1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    SGaist
                                    Lifetime Qt Champion
                                    wrote on 25 Nov 2020, 17:52 last edited by
                                    #17

                                    Not knowing your code base it's difficult to answer since we do not know what happens client side and we do not know how you handle the sending of message back to the client.

                                    One thing however is that it looks like you are making things more complicated than necessary. From your description, you seem to need a QTcpServer to get the connections and then a list of QTcpSocket for the exchange of messages. So I fail to see the need to subclass both of them in order to implement your proxy.

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    S 1 Reply Last reply 25 Nov 2020, 17:56
                                    1
                                    • S SGaist
                                      25 Nov 2020, 17:52

                                      Not knowing your code base it's difficult to answer since we do not know what happens client side and we do not know how you handle the sending of message back to the client.

                                      One thing however is that it looks like you are making things more complicated than necessary. From your description, you seem to need a QTcpServer to get the connections and then a list of QTcpSocket for the exchange of messages. So I fail to see the need to subclass both of them in order to implement your proxy.

                                      S Offline
                                      S Offline
                                      SPlatten
                                      wrote on 25 Nov 2020, 17:56 last edited by
                                      #18

                                      @SGaist , subclass or not subclass, the implementation would be the same?

                                      The clients all send the server regular heartbeats, if a client does not receive an ack in response to the heartbeat then it can determine that the server is no longer running and self terminate.

                                      From time to time the server will issue commands to the clients, its these that do not work.

                                      In trying to fix this I've managed to break everything so once I get it back up I will publish some source.

                                      Kind Regards,
                                      Sy

                                      K 1 Reply Last reply 25 Nov 2020, 21:34
                                      0
                                      • S Offline
                                        S Offline
                                        SGaist
                                        Lifetime Qt Champion
                                        wrote on 25 Nov 2020, 18:10 last edited by
                                        #19

                                        @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                                        @SGaist , subclass or not subclass, the implementation would be the same?

                                        Not necessarily, it depends on what your code does.

                                        Interested in AI ? www.idiap.ch
                                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        1 Reply Last reply
                                        0
                                        • S SPlatten
                                          25 Nov 2020, 17:56

                                          @SGaist , subclass or not subclass, the implementation would be the same?

                                          The clients all send the server regular heartbeats, if a client does not receive an ack in response to the heartbeat then it can determine that the server is no longer running and self terminate.

                                          From time to time the server will issue commands to the clients, its these that do not work.

                                          In trying to fix this I've managed to break everything so once I get it back up I will publish some source.

                                          K Offline
                                          K Offline
                                          KroMignon
                                          wrote on 25 Nov 2020, 21:34 last edited by KroMignon
                                          #20

                                          @SPlatten said in QTcpSocket / QTcpServer, two way communication:

                                          From time to time the server will issue commands to the clients, its these that do not work.
                                          In trying to fix this I've managed to break everything so once I get it back up I will publish some source.

                                          It looks to me as you want to reimplement TCP KeepAlive feature.
                                          Why do not simply activate KeepAlive option on TCP socket?

                                          But perhaps I don't understand very well your explanation.
                                          When you are talking about "server" and "client" do you mean the application or the socket?

                                          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                          1 Reply Last reply
                                          0

                                          1/23

                                          24 Nov 2020, 18:11

                                          • Login

                                          • Login or register to search.
                                          1 out of 23
                                          • First post
                                            1/23
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved