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. Connect to internet
Forum Updated to NodeBB v4.3 + New Features

Connect to internet

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 5 Posters 1.3k Views 3 Watching
  • 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.
  • D Offline
    D Offline
    deleted340
    wrote on last edited by
    #1

    I have created a small game for Android to be played between two players on different phones, using TCP. I have created a QTcpServer on one phone and have the other as a client. This works well when they are on the same WiFi, connecting with 192.168.1.x.

    However, I also want it to be possible to play when they are on different networks/mobile data. How can I accomplish this? I am very new to network programming and just have some very basic knowledge of networks in general. Is it easy to add this functionality to my application using QTcpServer and QTcpSocket? Do you know an easy-to-follow guide for this if it is a little more complicated?

    Thanks

    Pl45m4P 1 Reply Last reply
    1
    • D deleted340

      I have created a small game for Android to be played between two players on different phones, using TCP. I have created a QTcpServer on one phone and have the other as a client. This works well when they are on the same WiFi, connecting with 192.168.1.x.

      However, I also want it to be possible to play when they are on different networks/mobile data. How can I accomplish this? I am very new to network programming and just have some very basic knowledge of networks in general. Is it easy to add this functionality to my application using QTcpServer and QTcpSocket? Do you know an easy-to-follow guide for this if it is a little more complicated?

      Thanks

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @cludic

      To play over Internet you need some sort of public server, because you don't want to open your device to the whole world.
      It's not that easy to create Internet services and it's not possible using only QTcpSocket / QTcpServer, unless your server is already "public".


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      1
      • D Offline
        D Offline
        deleted340
        wrote on last edited by deleted340
        #3

        @Pl45m4

        Thanks for such a quick answer.

        So when I tell the QTcpServer to listen to QHostAddress::AnyIPv4, it is in fact only listening for devices on the local network?

        If this is the case, that means I can at least feel comfortable that my application is safe, right? (Unless someone hacks the network itself)

        How complicated is it to make one of the two phones a "public server" in a safe way?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi and welcome to devnet,

          You might also want to consider a P2P architecture. Valve for example has such a framework (disclaimer, I did not use it).

          This will allow you to not need to have one of the phone as server.

          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
          2
          • 8Observer88 Offline
            8Observer88 Offline
            8Observer8
            wrote on last edited by 8Observer8
            #5

            Write a server in Node.js and JavaScript. Deploy it on Heroku (it is a free hosing). Use WebSockets. This is my example how to connect Qt C++ using QWebSocket with Node.js: https://github.com/8Observer8/websocket-connection (Qt Client is included to repo) But I use TypeScript for server there. This is my JavaScript example that ready do deploy on Heroku: https://github.com/8Observer8/multiplayer-game-in-js It is simple to deploy on Heroku. Just create a new application on Heroku. Go to Deploy Section of Heroku and connect your app to repo (By clicking on Connect button and click "Deploy"

            app.js

            const express = require("express");
            const http = require("http");
            const ws = require("ws");
            const path = require("path");
             
            const app = express();
            app.use(express.static(path.join(__dirname, "./public")));
            app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")) });
             
            const httpServer = http.createServer(app);
            const wss = new ws.Server({ server: httpServer });
            wss.on("connection", (wss) => { console.log("connected") });
             
            const port = process.env.PORT || 3000;
            httpServer.listen(port, () => { console.log("Server started. Port: ", port) });
            

            Web client:

            public/index.html

            <!DOCTYPE html>
            <html lang="en">
             
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Document</title>
            </head>
             
            <body>
                <h1>Hello</h1>
                <script>
                    const ws = new WebSocket("wss://multiplayer-game-in-js.herokuapp.com");
                    ws.onopen =
                        () => {
                            console.log("connected");
                        }
                </script>
            </body>
             
            </html>
            
            1 Reply Last reply
            1
            • D Offline
              D Offline
              deleted340
              wrote on last edited by
              #6

              Thanks a lot for the suggestions, I will look in to them!

              I am still not sure how the QTcpServer works exactly. Is it only listening on the local network when using QHostAddress::AnyIPv4?

              Is it "safe" to use a QTcpServer that is listening for QHostAddress::AnyIPv4? I mean, if it is possible for computers outside the local network, is there any risks using it?

              After reading your posts, it sounds like it will take some time to make it possible to play over internet, so I think I will stick to the local network while I try to learn more. Do you have any other suggestions when using QTcpServer for a local network?

              Pl45m4P 1 Reply Last reply
              0
              • D deleted340

                Thanks a lot for the suggestions, I will look in to them!

                I am still not sure how the QTcpServer works exactly. Is it only listening on the local network when using QHostAddress::AnyIPv4?

                Is it "safe" to use a QTcpServer that is listening for QHostAddress::AnyIPv4? I mean, if it is possible for computers outside the local network, is there any risks using it?

                After reading your posts, it sounds like it will take some time to make it possible to play over internet, so I think I will stick to the local network while I try to learn more. Do you have any other suggestions when using QTcpServer for a local network?

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on last edited by Pl45m4
                #7

                @cludic said in Connect to internet:

                I am still not sure how the QTcpServer works exactly. Is it only listening on the local network when using QHostAddress::AnyIPv4?

                It seems like you don't know much about the IP-protocol, networking and routing...

                There are public IPs and your private network IPs.
                Public IPs are unique, while every private network uses the same private IP address range

                • 192.168.0.0 - 192.168.255.255
                • 172.16.0.0 - 172.31.255.255
                • 10.0.0.0 - 10.255.255.255

                Player A and player B could have the same local IP address when playing against each other over the internet, since they are in different local networks.
                -> Routing, NAT, etc

                QTcpServer won't create a public accessible "server" to connect to.

                So no device "from outside" can attack your client using your local IPv4 address. There is your local router which hides its private networks from the rest (when beeing in your WLAN) and your mobile ISP also uses firewalls and routing when you connect to the next cell tower (you also get a private address).

                BTW: The internet doesn't use IPv4 anymore. The connection between public routers is made with IPv6. If IPv4 packages are needed, they will be transferred inside IPv6 packages...
                but this is not a thing, you have to care about ;-)

                One possible way is, to open some ports on your local router and ask your ISP for static IPs.
                -> DONT do it!! Your local network would be an easier target to attack then.

                Safest way would be to rent some public server space and run your public app server from there. If you want to have a 247, (worldwide) game server.
                (I think, this is how most of the mobile games, like "Clash of Clans" work, except the dev studios have their own dedicated public game servers, which every "client" - your device - connects to, when starting the game. )

                Or just have a look at @8Observer8 and @SGaist suggestions.

                Read more about the stuff, you need there first and then think about what you are willing to do.

                It can not be done with your Qt code only.


                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                1 Reply Last reply
                6
                • D Offline
                  D Offline
                  deleted340
                  wrote on last edited by
                  #8

                  @Pl45m4

                  Thanks for such an informative answer! It certainly seems that I have a lot to learn, it was quite a bit more complicated than I thought. I will do some reading and also study the other suggestions in this thread before giving it another try.

                  Thanks again!

                  1 Reply Last reply
                  0
                  • 8Observer88 Offline
                    8Observer88 Offline
                    8Observer8
                    wrote on last edited by 8Observer8
                    #9

                    I made a simple example for you (with Qt Client and Node.js server). My example works like this:

                    • A client sends coordinates of mouse click to server.
                    • The server receives the coordinates and send them back to the client.
                    • The client receives the coordinates and shows them on the window.

                    I have: a Qt client, a web client, and a node.js server. I got the Qt client example from here: Echo Client Example If you want to run this example locally you should write:

                    m_webSocket.open(QUrl("ws://localhost:3000"));
                    

                    But if you what to connect to Heroku Node.js server you should write (change to your application name):

                    m_webSocket.open(QUrl("wss://mouse-click-js.herokuapp.com"));
                    

                    Deploying on Heroku is very simple. You should to create Heroku app and GitHub repo. Then just connect your app to your repo and click "Deploy" like on the screenshots:
                    ConnectToGitHub.png
                    ManualDeployAndAutomaticDeploy.png
                    You can run the web client: https://mouse-click-js.herokuapp.com/
                    Or the Qt release for Windows to test it: https://dl.dropboxusercontent.com/s/t4jvaehloajj3bd/MouseClickClient_ReleaseForWindows.zip
                    MouseClickClient_ReleaseForWindows.gif
                    What you need to deploy Qt client on Windows:
                    c06bb84a-8cbe-4105-bdbc-ec424aaecb6d-image.png

                    Source code of Qt Client: https://github.com/8Observer8/MouseClick_QtClient_Qt5Cpp
                    Source code of Node.js server: https://github.com/8Observer8/mouse-click-js

                    main.cpp

                    #include <QtWidgets/QApplication>
                    #include <QtWidgets/QWidget>
                    #include <QtWidgets/QLabel>
                    #include <QtWidgets/QVBoxLayout>
                    #include <QtGui/QMouseEvent>
                    #include <QtWebSockets/QWebSocket>
                    #include <QtCore/QJsonDocument>
                    #include <QtCore/QJsonObject>
                    #include <QtCore/QDebug>
                    
                    class Window : public QWidget {
                        Q_OBJECT
                    private:
                        QWebSocket m_webSocket;
                        QLabel m_connection;
                        QLabel m_output;
                    public:
                        Window(QWidget *parent = nullptr) : QWidget(parent) {
                            setWindowTitle("Qt C++ Client");
                            resize(300, 300);
                            QVBoxLayout *vbox = new QVBoxLayout(this);
                            QLabel *instruction = new QLabel("Click on the window.");
                            m_connection.setText("Wait for connection...");
                            QFont font = QFont("Arial", 14);
                            instruction->setFont(font);
                            m_connection.setFont(font);
                            m_output.setFont(font);
                            vbox->addWidget(instruction);
                            vbox->addWidget(&m_connection);
                            vbox->addWidget(&m_output);
                            vbox->addStretch(1);
                            connect(&m_webSocket, &QWebSocket::connected,
                                     this, &Window::onConnected);
                            // m_webSocket.open(QUrl("ws://localhost:3000"));
                            m_webSocket.open(QUrl("wss://mouse-click-js.herokuapp.com"));
                        }
                    private slots:
                        void onConnected() {
                            m_connection.setText("Connected to server");
                            connect(&m_webSocket, &QWebSocket::textMessageReceived,
                                    this, &Window::onMessageReceived);
                        }
                        void onMessageReceived(QString message) {
                            qDebug() << message;
                            QJsonDocument doc(QJsonDocument::fromJson(message.toUtf8()));
                            QJsonObject data = doc.object();
                            int x = data["x"].toInt();
                            int y = data["y"].toInt();
                            // Show data
                            m_output.setText(QString("Answer from server: %1, %2").arg(x).arg(y));
                        }
                    private:
                        void mousePressEvent(QMouseEvent *event) override {
                            Q_UNUSED(event);
                            qDebug() << event->x() << " " << event->y();
                            QJsonObject jsonObject;
                            jsonObject["x"] = event->x();
                            jsonObject["y"] = event->y();
                            QString message = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
                            m_webSocket.sendTextMessage(message);
                        }
                    };
                    
                    #include "main.moc"
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication a(argc, argv);
                        Window w;
                        w.show();
                        return a.exec();
                    }
                    

                    package.json

                    {
                      "name": "mouse-click-js",
                      "version": "1.0.0",
                      "description": "",
                      "main": "app.js",
                      "scripts": {
                        "test": "echo \"Error: no test specified\" && exit 1",
                        "start": "node app.js"
                      },
                      "keywords": [],
                      "author": "",
                      "license": "ISC",
                      "dependencies": {
                        "express": "^4.17.1",
                        "ws": "^7.3.1"
                      }
                    }
                    

                    app.js

                    const express = require("express");
                    const http = require("http");
                    const ws = require("ws");
                    const path = require("path");
                    
                    const app = express();
                    app.use(express.static(path.join(__dirname, "./public")));
                    app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")) });
                    
                    const httpServer = http.createServer(app);
                    const wss = new ws.Server({ server: httpServer });
                    wss.on("connection",
                        (ws) =>
                        {
                            console.log("Client connected");
                            ws.onmessage =
                                (event) =>
                                {
                                    const msg = JSON.parse(event.data);
                                    console.log(msg.x + ", " + msg.y);
                                    // Send an answer
                                    const resp = {
                                        x: msg.x,
                                        y: msg.y
                                    }
                                    ws.send(JSON.stringify(resp));
                                }
                        });
                    
                    const port = process.env.PORT || 3000;
                    httpServer.listen(port, () => { console.log("Server started. Port: ", port); });
                    

                    index.html

                    <!DOCTYPE html>
                    <html lang="en">
                    
                    <head>
                        <meta charset="UTF-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                        <title>Web Client</title>
                    </head>
                    
                    <body>
                        <h3>Click on the window.</h3>
                        <div id="output" style="font-family: Arial; font-size: 14px;"></div>
                    
                        <script>
                            const output = document.getElementById("output");
                            output.innerHTML = "Wait for connection...";
                            // const ws = new WebSocket("ws://localhost:3000");
                            const ws = new WebSocket("wss://mouse-click-js.herokuapp.com");
                            ws.onopen =
                                () => {
                                    output.innerHTML = "Connected to the server";
                                    window.onclick = (event) => {
                                        const x = event.clientX;
                                        const y = event.clientY;
                                        console.log(x + ", " + y)
                                        ws.send(JSON.stringify({x: x, y: y}));
                                    };
                    
                                    ws.onmessage = (event) => {
                                        console.log(event.data);
                                        const msg = JSON.parse(event.data);
                                        output.innerHTML = `Answer from server: x = ${msg.x}, y = ${msg.y}`;
                                    }
                                };
                        </script>
                    </body>
                    
                    </html>
                    
                    1 Reply Last reply
                    5
                    • D Offline
                      D Offline
                      deleted340
                      wrote on last edited by
                      #10

                      @8Observer8

                      Thanks so much for taking the time to create this example, it will be really helpful!

                      1 Reply Last reply
                      1
                      • J Offline
                        J Offline
                        Johndavid
                        wrote on last edited by
                        #11
                        This post is deleted!
                        1 Reply Last reply
                        0

                        • Login

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