QTcpSocket connected, but server doesn't receive data



  • Hello everyone.

    I am implementing a server with Qt 5.2 which connects to a server implemented in standard C++ (which uses standard linux lib for socket).

    My client is connecting to the server without any problems, but when I try to send something, the server doesn't receive anything, and when I look on my network activity with Wireshark, it seems that my client doesn't send anything at all because I only see TCP packet for connection establishement.

    The TCP socket is in a separate thread from the GUI, but the socket is created inside this thread, so I don't think it is a thread problem. Plus, when I debug and print the result of write functions it writes 4 or 5 (based on the string I have sent) but doesn't send anything.

    Here is my class which contains the thread
    ThreadSending.h
    @
    /**

    • @brief thread establishing connection with server and sends data to the server
    • inherits from QThread
      /
      class ThreadSending : public QThread
      {
      Q_OBJECT
      public:
      /
      *
      • @brief constructor, initiliaze IP and port
      */
      ThreadSending();

    public slots:
    /**
    * @brief the slot which receives signals sent by MainWindow
    *
    * @param val the string emitted
    */
    void addValueToList(QString val);

    private:
    /**
    * @brief method call when the thread starts
    *
    */
    void run();

    QString serverIP; /**< the IP of the server */
    int portWrite; /**< the port where it connects */
    QList <QString> toSend; /**< list of data to send */
    QMutex mutex; /**< mutex used to avoid concurrent access on list */
    

    };
    @

    ThreadSending.cpp

    @
    /**************** Sending thread *********************/
    ThreadSending::ThreadSending() : QThread()
    {
    serverIP = "192.168.0.4";
    portWrite = 1234;
    }

    void ThreadSending::addValueToList(QString val)
    {
    mutex.lock();
    toSend.append(val);
    qDebug()<<"new value to send : "<<val;
    mutex.unlock();
    }

    void ThreadSending::run()
    {
    QTcpSocket* sckWrite = new QTcpSocket();
    sckWrite->connectToHost(serverIP,portWrite);
    if(sckWrite->waitForConnected(-1))
    {
    qDebug()<<"connect sending";
    while (true)
    {
    string data = "";
    if(!toSend.isEmpty())
    {
    mutex.lock();
    data = toSend.first().toStdString();

                toSend.removeFirst();
                mutex.unlock();
    
                QString dt = QString::fromStdString(data+"\n");
                QByteArray array;
                array.append(dt);
    
                qDebug()<<"state "<<sckWrite->state();
    
                qDebug()<<"send "<<sckWrite->write(array)<<" bytes";
    
                //sckWrite->flush();
                //sckWrite->close();
            }
        }
    }
    else
        qDebug()<<"fail to connect sending";
    

    }
    @

    and my main.cpp

    @
    int main(int argc, char *argv[])
    {
    qInstallMessageHandler(debugOutput);

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    ThreadSending* ts = new ThreadSending();
    //ThreadReceiving* tr = new ThreadReceiving();
    QObject::connect(&w, SIGNAL( valueToSend(QString) ), ts, SLOT( addValueToList(QString) ));
    ts->start();
    //tr->start();
    
    return a.exec(&#41;;
    

    }
    @

    Qt client is running on Windows 7 64bits with Qt5.2.1 and the server is runing on Ubuntu 12.04LTS 32bits
    Thank you for your help


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Can you also post the code from the server ?



  • Thanks a lot.

    Here is my server implementation (at least for the communication with the client)

    ClientConnection.h
    @
    #ifndef CLIENTCONNECTION_INCLUDED
    #define CLIENTCONNECTION_INCLUDED

    #include <cstdio>
    #include <cstdlib>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <strings.h>

    #include "SynchronizedList.h"

    class ClientConnectionReading
    {
    public:
    ClientConnectionReading(SynchronizedList* o);
    ~ClientConnectionReading();

    void initConnection();

    bool waitForClient();
    bool waitForDataReception();

    void connectionLoop();

    private:
    int sck;
    int clientSocket;
    int port;
    struct sockaddr_in serv_addr;
    struct sockaddr_in cli_addr;

    SynchronizedList* obj;
    };

    #endif // CLIENTCONNECTION_INCLUDED
    @

    ClientConnection.cpp
    @
    #include "ClientConnection.h"

    ClientConnectionReading::ClientConnectionReading(SynchronizedList* o)
    {
    obj = o;
    }
    ClientConnectionReading::~ClientConnectionReading()
    {

    }

    void ClientConnectionReading::initConnection()
    {
    sck = socket(AF_INET, SOCK_STREAM, 0);
    if (sck < 0)
    std::cout<<"ERROR opening socket";

    bzero((char *) &serv_addr, sizeof(serv_addr));
    port = 1234;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(port);
    

    }

    bool ClientConnectionReading::waitForClient()
    {
    int clilen;
    if (bind(sck,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
    std::cout << "ERROR on binding";
    std::cout << "waiting for client";
    listen(sck,5);
    clilen = sizeof(cli_addr);
    clientSocket = accept(sck, (struct sockaddr ) &cli_addr, (socklen_t)&clilen);
    return true;
    }
    bool ClientConnectionReading::waitForDataReception()
    {
    int n = 0;
    char buffer[256];
    do{
    bzero(buffer,256);
    printf("before read\n");
    //sleep(1);
    n = read(clientSocket,buffer,255);
    printf("after read\n");
    //sleep(1);
    if(n==-1 || n==0)
    {
    printf("Error while reading\n");
    getchar();//wait for key strike
    }

        printf("received : %s , n : %d\n",buffer,n);
        obj->addElement( std::string(buffer) );
    } while ( true );
    return true;
    

    }

    void ClientConnectionReading::connectionLoop()
    {
    std::cout << "launching reading process";
    sleep(1);
    initConnection();
    waitForClient();
    waitForDataReception();
    }
    @

    and the main
    @
    #include "ClientConnection.h"
    #include "ClientConnectionSending.h"
    #include "HardwareCommunication.h"
    #include <pthread.h>

    void* readingThread(void* ptr)
    {
    ClientConnectionReading* obj = (ClientConnectionReading*)ptr;
    obj->connectionLoop();
    return NULL;
    }

    void* sendingThread(void* ptr)
    {
    ClientConnectionSending* obj = (ClientConnectionSending*)ptr;
    obj->connectionLoop();
    return NULL;
    }

    int main()
    {
    std::cout<<"start sever"<<std::endl;
    pthread_t t_send,t_receive;
    SynchronizedList* actionList = new SynchronizedList();
    SynchronizedList* sendList = new SynchronizedList();
    ClientConnectionReading* read = new ClientConnectionReading(actionList);
    ClientConnectionSending* send = new ClientConnectionSending(sendList);
    HardwareCommunication hwCom;

    pthread_create(&t_send,NULL,sendingThread,send);
    pthread_create(&t_receive,NULL,readingThread,read);
    std::cout << "thread launch, entering main loop"<<std::endl;
    while(1) //main thread of the app
    {
    if(sendList->isEmpty())
    {
    sleep(1);
    }
    else
    {
    std::string val = sendList->getFirstElement();
    std::string head = val.substr(0,2);
    if(head.compare("x:"))
    {
    std::string strOffset = val.substr(2);
    hwCom.setXaxis( atoi(strOffset.c_str()) );
    }
    if(head.compare("y:"))
    {
    std::string strOffset = val.substr(2);
    hwCom.setYaxis( atoi(strOffset.c_str()) );
    }
    if(head.compare("z:"))
    {
    std::string strOffset = val.substr(2);
    hwCom.setZaxis( atoi(strOffset.c_str()) );
    }
    }
    }
    delete read;
    return 0;
    }
    @

    Also I have implemented the following code in Java for testing purpose :
    @
    package test_serv;

    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    /**

    • @author Vince
      */
      public class Test_serv {

      /**

      • @param args the command line arguments
        */
        public static void main(String[] args) {
        Socket sck;
        OutputStream os;
        try {
        String test = "test";
        sck = new Socket("192.168.0.4",1234);
        os = sck.getOutputStream();
        os.write(test.getBytes());
        } catch (UnknownHostException ex) {
        Logger.getLogger(Test_serv.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
        Logger.getLogger(Test_serv.class.getName()).log(Level.SEVERE, null, ex);
        }
        }
        }
        @

    And it works (the server receives test correctly).


  • Lifetime Qt Champion

    One thing that puzzles me is why are you converting a QString to a std string to convert it right after to a QString and then to a QByteArray ?

    You also don't provide any means to stop your thread.

    I would recommend that you take a look at the Fortune Server/Client examples to have a better understanding on how you can use these classes without the need of threads


Log in to reply
 

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