[Solved] Two Concerns



  • Hello, everyone! I hope I'm not out of line by asking for this kind of help.

    I'm trying to create a client/server application. The server is looking really good. I used the FortuneServer example to get it to start listening... But, I noticed that each time the server is ran, the port it listens on changes...

    @void MainWindow::beginListening(){
    QNetworkConfigurationManager manager;

    if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
        // Get saved network configuration
        QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
        settings.beginGroup(QLatin1String("QtNetwork"));
        const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
        settings.endGroup();
    
        // If the saved network configuration is not currently discovered use the system default
        QNetworkConfiguration config = manager.configurationFromIdentifier(id);
        if ((config.state() & QNetworkConfiguration::Discovered) !=
            QNetworkConfiguration::Discovered) {
            config = manager.defaultConfiguration();
        }
    
        networkSession = new QNetworkSession(config, this);
        //connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
    
        addText("Opening network session.");
        //statusLabel->setText(tr("Opening network session."));
        networkSession->open();
    } else {
        sessionOpened();
    }
    

    }

    void MainWindow::sessionOpened()
    {
    // Save the used configuration
    if (networkSession) {
    QNetworkConfiguration config = networkSession->configuration();
    QString id;
    if (config.type() == QNetworkConfiguration::UserChoice)
    id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
    else
    id = config.identifier();

        QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
        settings.beginGroup(QLatin1String("QtNetwork"));
        settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
        settings.endGroup();
    }
    

    //! [0] //! [1]
    tcpServer = new QTcpServer(this);
    if (!tcpServer->listen()) {
    QMessageBox::critical(this, tr("Server"),
    tr("Unable to start the server: %1.\n")
    .arg(tcpServer->errorString()));
    close();
    return;
    }

    //! [0]
    QString ipAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // use the first non-localhost IPv4 address
    for (int i = 0; i < ipAddressesList.size(); ++i) {
    if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
    ipAddressesList.at(i).toIPv4Address()) {
    ipAddress = ipAddressesList.at(i).toString();
    break;
    }
    }

    // if we did not find one, use IPv4 localhost
    if (ipAddress.isEmpty())
        ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
        addText(tr("The server is running on\nIP: %1\nPort: %2")
                .arg(ipAddress)
                .arg(tcpServer->serverPort()));
    

    //! [1]
    }@

    There is the beginListening function, with which I shoved the configure code in (the constructor method from the FortuneServer example, pretty much) and then there's the SessionOpened function that gets called afterwards. I've read, reread, and triple read the code and I can't seem to figure out how it does whatever it does. I just know that it does. XD Now, to run a server that is to serve multiple clients, I can't have the server's port change every time it's ran... Is there a way to get the server to listen on a specific port, every time?

    And my second question is a little more broader... I'm used to 2D programming in VB using the Picture Box control and DirectX... Is there an equivalent method I could use with Qt? Obviously, I don't want to use DirectX, so maybe OpenGL? Idk, I don't need help as much as I need to be pushed in the right direction to achieve my goals.

    Thanks for anyone who responds. :D


  • Lifetime Qt Champion

    Hi,

    For the server port number simply set it when you call "listen":http://qt-project.org/doc/qt-4.8/qtcpserver.html#listen Have a look at the function arguments.

    As for your second question, it depends on what you want to do: you could also use "QGraphicsScene":http://qt-project.org/doc/qt-4.8/qgraphicsscene.html

    You have to be more specific :)

    Hope it helps



  • Ah, okay. You're right; maybe I wasn't clear.

    I see tcpServer->Listen... However, it's in an if statement, preceded by a not operator.

    I'm confused by this...

    @if (!tcpServer->listen(QHostAddress::Any, 5000))@
    listens on the port I want it to listen on; thank you for that. However, shoving that function in an if statement with a not operator... I don't understand how to read that. All I know is that it does what it's intended to do... Could you explain that to me a bit?

    Going back to the graphics aspect; in VB, I had a picture box control. Using DirectX, I would read the graphics from a file and placed them on 'surfaces'. Then I would take portions of the surface, and place it onto something called a rect, (rectangle, lol) made out of the picture box. (I think Dx refered to this as bliting...) The picture box would then display anything I placed on the rect... I'll see if QGraphicsScene supplies me with what I need. But maybe the method I used could shed some light on how you could advise me on how to reproduce that method, maybe.

    I dunno, maybe I have to take a completely new approach to it. I just need to know where to start, and what to study/play around with.



  • Hope this helps. :)

    @//! [0] //! [1]
    tcpServer = new QTcpServer(this);
    if (!tcpServer->listen(QHostAddress::Any, 5000)) {
    //Throw error, if connection IS NOT found
    //using port 5000 from any address
    close();
    return;
    }@

    Works the same as if it wasn't in a !tcpServer.

    @//! [0] //! [1]
    tcpServer = new QTcpServer(this);
    if (tcpServer->listen(QHostAddress::Any, 5000)) {
    //Do server stuff, if connection IS found
    //using port 5000 from any address
    close();
    return;
    }@

    You just change what is executed within the statement.


  • Lifetime Qt Champion

    For the graphics part, it really depends on what you want to have in the end. If it's only showing images from file a QImage/QPixmap + QLabel combo might be enough.



  • Ugh, I feel like such a bother but I'm not sure if I'm doing this right.

    Been Googling examples and other projects that use QTcpSocket/QTcpServer, and in all of them, including the Fortune Client example, they make use of the connectToHost function to establish a connection.

    I have this written out

    @void MainWindow::establishConnection(){
    tcpSocket->connectToHost("localhost", 5000);
    }@

    which is called in the constructor method of this object. Every time the program starts, it crashes. it compiles just fine, however; so I'm thinking it's a run time error, though it isn't letting me know what exactly it is I'm doing wrong.

    I even tried to move it to a push button click event. The program loads, but once the button is clicked, it crashes. So I think it's whenever I try to call the connectToHost is when my program crashes. Maybe I'm doing something wrong? I dunno.

    Also, I tried using 127.0.0.1 instead of localhost. Still no luck. :(

    Anyone have any insight on what the problem could be?

    [edit] Nevermind, I got it running. Now to mess around. Thanks for all the help, guys! :)


  • Lifetime Qt Champion

    Great !

    If everything is fine now, could you update the thread's title to solved so other forum users may know that you found a solution ?



  • [quote author="SGaist" date="1364760821"]Great !

    If everything is fine now, could you update the thread's title to solved so other forum users may know that you found a solution ?[/quote]

    And what you did to fix it? :)



  • Oh, sure.

    I have this

    @void MainWindow::establishConnection(){
    tcpSocket->connectToHost("localhost", 5000);
    }@

    Which is called in my constructor.

    I had
    @establishConnection();@

    without doing

    @tcpSocket = new QTcpSocket(this);@

    So far, using pointers has been really tripping me up, and tbh I'm still unsure of 75% of their use. I just know that in this case, it caused my program to crash without it.

    And another question has come up. I've been trying at this for about two hours now, searching the forums and Google to no avail. All I'm trying to do is...

    @...
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(processConnection()));
    }@
    in a function called beginListening.

    Whenever my client is opened, it immediately establishes a connection with the server, making processConnection run. k. Here's my processConnection function.

    @// process new connections...
    void MainWindow::processConnection(){
    if (tcpServer->hasPendingConnections()){
    onlinePlayers++;
    //cout << onlinePlayers << endl;

        player[onlinePlayers] = new QTcpSocket();
        player[onlinePlayers] = tcpServer->nextPendingConnection();
        addText(tr("New connection received from %1.")
                .arg(player[onlinePlayers]->peerAddress().toIPv4Address()));
        
        //testing junk
        addText(player[onlinePlayers]->peerAddress().toString());
    }
    

    }@

    in an attempt to display to the server that a new connection has indeed been accepted, and then I want to save that connection in my own defined array of QTcpSockets. So far, everything seems to go well until we get to the part where I'm trying to return the host connection's IP address. When I use the .toIPv4Address() call, it returns 0. When I use the toString() call, it returns a strange string "::1%0". Even did a Google search on that string, with no luck.


Log in to reply
 

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