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

QTcpSocket NetworkError with Wifi OK but Internet NOK



  • Hello !

    After a few days of digging, here is the situation:
    I use QTCPSocket to transfer datas from a Windows client to a Linux system server.

    The server is configured as a Wifi AP without internet connection.

    When the client is connected to the server through Wifi, without internet, I hit NetworkError as soon as I try send/receive datas.

    But if the client is additionnaly connected to internet through ethernet, everything works perfectly.

    Can someone helps me / explain me the issue please ? ?



  • Here some additional information :

    • On one side, I have a raspberry pi configured as a wifi access point. I have my "server code" using QtcpServer on it.

    • On the other side, I have a PC running the "client code" using QtcpSocket.

    • The PC connects without any problem to the wifi access point, I can use SSH and VNC viewer from the PC to the raspberry.

    • In my "client" code, when I use my_client->connectToHost("ip addr server", port), it works well when my PC (so the client in this case) is connected to the internet with an ethernet cable.

    • If I unplug the ethernet cable from my PC (so it doesn't have access to the internet) BUT it is connected to the server wifi access point, my_client->connectToHost(...) hits the error QAbstractSocket::NetworkError.

    The issue is that I want to use my application offline. Is that possible to use QtcpSocket through a wifi AP without being connected to the internet ?

    It's been 3 days I am struggling with that issue, some help would be very appreciated :) !


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but are you updating the server address after pulling the cable out ?



  • the giveaway is that when the client has inet connection it works..that tells me it is a routing problem on the client.



  • @SGaist Hi, no I am not updating the server address after pulling the cable out.

    Here is the method that connects the client to the server's wifi ap, it works well in any case :

    void MyClass::connectionWifi()
    {
        _connectionAttempts++;
        qDebug()<<"@@ Connection wifi";
        QString resultDisk;
        QProcess process;
        int returnCode = process.execute("netsh wlan connect name=wifiAp");
    
        process.start("netsh wlan show networks");
        process.waitForFinished();
        resultDisk = process.readAllStandardOutput();
    
        if(returnCode==0){
            if(resultDisk.contains("wifiAp")){
                ui->label_statutWifi->setText(tr("Détecté"));
                connection();
            }else{
                ui->label_statutWifi->setText(tr("Non connecté"));
                ui->label_connect->setText(tr("Outil non détecté"));
            }
    
        }else{
            ui->label_statutWifi->setText(tr("Wifi de la tablette éteind"));
            ui->label_connect->setText(tr("Activez le WiFi"));
        }
    }
    

    And here is the method that connects the client to the server, that works only when the client has internet access through ethernet cable, in the other case the "connectToHost" method hits "QAbstractSocket::NetworkError" :

    void MyClass::connection()
    {
        ui->label_connect->setText(tr("Connecting..."));
        _client->connectToHost("192.168.xx.xx", portNumber);
    }
    

    And _client is initialized at the beginning of my code as following :
    myClass.h :

    QTcpSocket *_client;
    

    myClass.cpp :

    _client = new QTcpSocket(this);
    


  • @Kent-Dorfman Hi, do you mean that the problem is caused because of my PC (client) network settings ? Or do you think the cause is my code ?



  • @Match0um said in QTcpSocket NetworkError with Wifi OK but Internet NOK:

    do you mean that the problem is caused because of my PC (client) network settings ? Or do you think the cause is my code ?

    Each network interface has his own IP address, so if you use another interface (WIFI <=> LAN), the IP address will not be the same.
    This mean you have to update TCP remote IP and start a new connection.



  • @KroMignon Hi, the problem is that I do not change of wifi interface...

    To be clearer, I do not unplug the network cable while I am running the app.

    • 1st case : I run my app when my PC is only connected to the server side wifi access point (so my PC has an IP address related to this access point). In this case I am not able to connect to the related server (QAbstractSocket::NetworkError).
    • 2nd case : I run my app when my PC is connected to the server side wifi access point AND the ethernet cable of another network that gives my PC access to the internet is plugged in my PC. In this case I am able to connect to the server which is not related to the other network at all.

    And what I don't understand, is why QAbstractSocket->connectToHost() doesn't work in the first case, knowing that there is only 1 network available which is the wifi access point of the server...



  • That's weird, do you have any router setting on your windows?
    I often connect to the server through a private WIFI network without internet/cable, that shouldn't be a problem (but my server is not a WIFI AP and I connect to WIFI using system setting, not from my code).



  • @Bonnie The only setting I have changed on the laptop is :

    • As the Wifi AP has a hidden SSID, I hadded the profile with the command "netsh wlan add profile filename="C:...\wifiProfile.xml". That's all.
      Here is the xml file :
    <?xml version="1.0" encoding="US-ASCII"?>
    <WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
        <name>wifiName</name>
        <SSIDConfig>
            <SSID>
                <name>wifiName</name>
            </SSID>
        </SSIDConfig>
        <connectionType>ESS</connectionType>
        <connectionMode>auto</connectionMode>
        <MSM>
            <security>
                <authEncryption>
                    <authentication>WPA2PSK</authentication>
                    <encryption>AES</encryption>
                    <useOneX>false</useOneX>
                </authEncryption>		
    			<sharedKey>
    				<keyType>passPhrase</keyType>
    				<protected>false</protected>
    				<keyMaterial>password</keyMaterial>
    			</sharedKey>
            </security>
        </MSM>
    </WLANProfile>
    
    • When I run my code, I can see through windows network settings that I am connected to the wifi ap.

    • I also can establish ssh and vnc connections easily in any cases.

    I tested on several PCs, the behavior is the same. When connected to the internet it works, if not, the connection with the wifi AP fails.



  • One more information,
    When I turn on my raspberry (so the server), and that my PC (client) has not the ethernet cable pugged in, it works only once (so the first connectToHost() attemps works, then it doesn't work anymore). So I have to restart again and again my raspberry to be able to connect only once with _client->connectToHost().
    That makes no sense.

    Here what I have done with the server :

    _server = new QTcpServer(this);
    connect(_server, &QTcpServer::newConnection, this,   &myClass::newClient);
    _server->listen(QHostAddress::Any, portNumber);
    

    But for me, the issue can't be from the server side.
    Simply because the client hits AbstractSocket::NetworkError without any delay. When I don't get this error (so when the ethernet cable is plugged in the PC), it takes a minimum time to establish the connection.


  • Lifetime Qt Champion

    Do you mean when there's a client connecting to it ?
    Or when you start listening ?

    Just thinking out loud, do you have a firewall setup when your device is in AP mode ?



  • @SGaist The issue occurs when the client tries to connect to the server :

    • In the case where it works (ethernet cable plugged in the PC (client)) : If the client tries to connect to the server while the server is not listening, the client hits something like QAsbtractSocket::ConnectionRefusedError or QAbstractSocket::SocketTimeoutError.
    • But in the case where it doesn't work (client doesn't have access to the internet), it hits QAbstractSocket::NetworkError without any delay.

    I don't have any firewall parameter on my raspberry. Here is the AP config (hostapd.conf) :

    country_code=FR
    interface=wlan0
    ssid=wifiAP
    hw_mode=g
    channel=7
    wmm_enabled=0
    macaddr_acl=0
    ignore_broadcast_ssid=1
    auth_algs=1
    wpa=2
    wpa_passphrase=passwrd
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP
    

    What I was thinking about, maybe the MAC address (or another parameter) of my PC or my raspberry is not authorized on the other device. I had connected the raspberry to the same ethernet network once few weeks ago. Maybe it changed something to the settings ?



  • I can confim you guys that the issue comes from the client side.

    With my client offline (so no ethernet cable plugged in), I can connect the PC to the raspberry in SSH with Putty or cmd.
    So in Qt, I decided to change the port number to 22 (ssh) in _client->connectToHost(ip, port 22). The behavior is exactly the same as explained before. It fails when the client is offline, it works when the client is online.
    So the issue comes from Qt, or my code. But I don't know what.



  • @Match0um said in QTcpSocket NetworkError with Wifi OK but Internet NOK:

    I hit NetworkError

    Could you please share the error? Specially the error string...



  • @Pablo-J-Rogina Hi, here is how I manage errors (I added the error string) :

    connect(_client, SIGNAL(error(QAbstractSocket::SocketError)), this SLOT(error(QAbstractSocket::SocketError)));
    
    void myClass::error(QAbstractSocket::SocketError error)
    {
        qDebug() << "ERROR " << error;
        qDebug()<< "Error string "<<_client.errorString();
    }
    

    So in the App output I get :
    "ERROR QAbstractSocket::NetworkError".
    Error string "Host unreachable"

    I also ran my code in debug mode but I have no additionnal information about the error :/



  • Ok guys, I finally found what causes the problem :

    It is in my method connectionWifi() :

    void MyClass::connectionWifi()
    {
        _connectionAttempts++;
        qDebug()<<"@@ Connection wifi";
        QString resultDisk;
        QProcess process;
        int returnCode = process.execute("netsh wlan connect name=wifiAp");
    
        process.start("netsh wlan show networks");
        process.waitForFinished();
        resultDisk = process.readAllStandardOutput();
    
        if(returnCode==0){
            if(resultDisk.contains("wifiAp")){
                ui->label_statutWifi->setText(tr("Détecté"));
                connection();
            }else{
                ui->label_statutWifi->setText(tr("Non connecté"));
                ui->label_connect->setText(tr("Outil non détecté"));
            }
    
        }else{
            ui->label_statutWifi->setText(tr("Wifi de la tablette éteind"));
            ui->label_connect->setText(tr("Activez le WiFi"));
        }
    }
    

    If I comment this line it works well :

    int returnCode = process.execute("netsh wlan connect name=wifiAp");
    

    I don't know why this line makes the code not working when the the ethernet cable is unplugged (the ethernet network has no link with the wifi network I am trying to connect to).



  • @Match0um said in QTcpSocket NetworkError with Wifi OK but Internet NOK:

    int returnCode = process.execute("netsh wlan connect name=wifiAp");

    Try unplugging ethernet cable and run netsh wlan connect name=wifiAp from a Command Prompt. What happens, does it block?



  • @JonB It does not block when I run this command, I get the output " the connection request was successful"


  • Lifetime Qt Champion

    Then try again in your code but building the parameter list rather than passing the complete command as a string.

    I guess there's an issue with the = part.



  • This post is deleted!


  • @SGaist Did you mean something like that ? :

    QString cmd = "netsh";
    QStringList arguments;
    arguments <<"wlan"<<"connect"<<"name=mScan";
    int returnCode = process.execute(cmd, arguments);
    

    It doesn't change the behavior, I have the output "the connection request was successful", it connects my PC to the wifi access point, but if I run this commend the connectToHost method hits NetworkError.



  • @Match0um
    Yes, that is what @SGaist intended. We wanted to to verify that the element name=mScan was passed as a single argument.

    Whatever the issue is, it must be related, somehow, to the consequences of (successfully) running the command, not the act of running the command itself.



  • @Match0um said in QTcpSocket NetworkError with Wifi OK but Internet NOK:

    Error string "Host unreachable"

    This is a routing issue. You may want to capture and analyze network traffic (i.e. using Wireshark) to see what's going on under your Qt app depending on what connections (wireless or wired) you have on your client PC


Log in to reply