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. Loop running with Qt running on side
Qt 6.11 is out! See what's new in the release blog

Loop running with Qt running on side

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 2.0k Views 1 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.
  • T Offline
    T Offline
    TimeStrecher
    wrote on last edited by A Former User
    #1

    Hello everyone,
    I am on a small project and I ran into a problem. I need to run a for loop for the server to liste to new connections. Qt app will either freeze or stop being active until the loop is done. But I need both to run at the same time. I tried with threads, but the thread makes the app crash unless I call thread.join() which will make the app freeze until the thread is finish. So I'm stuck and I have no idea how to proceed. Thanks for the help and here is the project.

    #include "serveur.h"
    
    
    Server::Server(int PORT, bool broadcastPublic = false): QWidget()
    {
    	WSADATA wsaData;
    	WORD dllVersion = MAKEWORD(2, 1);
        Window();
    
    	if (WSAStartup(dllVersion, &wsaData) != 0)//starting winsock and check sucessfull startup
    	{
            QMessageBox::critical(this, "Error", "Winsock Startup Failed");
    		exit(1);
    	}
    
    	if (broadcastPublic == true)//check if server open to public
    	{
    		m_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    	}
    	else//server open to local only
    	{
    		m_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    	}
    
    	m_addr.sin_port = htons(PORT);//port used
    	m_addr.sin_family = AF_INET;//get IPv4 connections
    	m_sockListen = socket(AF_INET, SOCK_STREAM, NULL);//creating listening socket
    
    	if (bind(m_sockListen, (SOCKADDR*)&m_addr, sizeof(m_addr)) == SOCKET_ERROR)//bind the port to socket
    	{
            QString errorMsg = QStringLiteral("Failed to bind to our listening port. Winsock error: %1").arg(WSAGetLastError());
            QMessageBox::critical(this, "Error", errorMsg);
    		exit(1);
    	}
    
    	if (listen(m_sockListen, SOMAXCONN) == SOCKET_ERROR)
    	{
            QString errorMsg = QStringLiteral("Listening socket failed. Winsock error: %1").arg(WSAGetLastError()) ;
            QMessageBox::critical(this, "Error", errorMsg);
    		exit(1);
    	}
    
    	serverPtr = this;
    }
    
    void Server::Window()//setting up the interface
    {
        setFixedSize(600, 400);
    
        m_start = new QPushButton("Start Server");
        m_shut  = new QPushButton("Shut Down");
        QTextEdit *log = new QTextEdit;
    
        log->setReadOnly(true);
        log->setFont(QFont("Courier"));
        log->setLineWrapMode(QTextEdit::NoWrap);
    
        QHBoxLayout *footer = new QHBoxLayout();
        footer->addWidget(m_start);
        footer->addWidget(m_shut);
    
        QGridLayout *window = new QGridLayout();
        window->addWidget(log, 0, 1);
        window->addLayout(footer, 1, 0, 1, 2);
    
        setLayout(window);
    
        //QObject::connect(m_start, SIGNAL(clicked()), this, SLOT(ServerLaunch()));
        QObject::connect(m_shut, SIGNAL(clicked()), this, SLOT(close()));
    
    }
    
    bool Server::ListenNewConnections()//method i call in loop
    {
        SOCKET newConnection = accept(m_sockListen, (SOCKADDR*)&m_addr, &m_addrSize);
    
        if (newConnection == 0)
        {
            std::clog << "Failed to accept the client's connection." << std::endl;
            return false;
        }
        else
        {
            std::clog << "Client Connected! ID:" << m_totalConnections << std::endl;
            m_connections[m_totalConnections].socket = newConnection;
            CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandlerThread, (LPVOID)(m_totalConnections), NULL, NULL);
            m_totalConnections += 1;
            return true;
        }
    }
    
    void Server::ClientHandlerThread(int ID)
    {
    	PacketType _packetType;
    	while (true)
    	{
    		if (!serverPtr->GetPacketType(ID, _packetType)) //Get packet type
    			break; //If there is an issue getting the packet type, exit this loop
    		
    		if (!serverPtr->ProcessPacket(ID,_packetType))
    			break; //If there is an issue processing the packet, exit this loop
    	}
    	std::cout << "Lost connection to client ID: " << ID << std::endl;
    	closesocket(serverPtr->m_connections[ID].socket);
    }
    
    
    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      Hi! Using another thread was the right idea, but it shouldn't crash of course :-) Here's a guide on How To Really, Truly Use QThreads.

      1 Reply Last reply
      1
      • T Offline
        T Offline
        TimeStrecher
        wrote on last edited by
        #3

        I still get the app not responding.

        Server::Server(int PORT, bool broadcastPublic): QWidget()
        {
            QThread *thread = new QThread;
            QObject::connect(thread, SIGNAL(started()), this, SLOT(ServerRunning()));
            thread->start();
        
        	WSADATA wsaData;
        	WORD dllVersion = MAKEWORD(2, 1);
            Window();
        
        	if (WSAStartup(dllVersion, &wsaData) != 0)//starting winsock and check sucessfull startup
        	{
                QMessageBox::critical(this, "Error", "Winsock Startup Failed");
        		exit(1);
        	}
        
        	if (broadcastPublic == true)//check if server open to public
        	{
        		m_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        	}
        	else//server open to local only
        	{
        		m_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        	}
        
        	m_addr.sin_port = htons(PORT);//port used
        	m_addr.sin_family = AF_INET;//get IPv4 connections
        	m_sockListen = socket(AF_INET, SOCK_STREAM, NULL);//creating listening socket
        
        	if (bind(m_sockListen, (SOCKADDR*)&m_addr, sizeof(m_addr)) == SOCKET_ERROR)//bind the port to socket
        	{
                QString errorMsg = QStringLiteral("Failed to bind to our listening port. Winsock error: %1").arg(WSAGetLastError());
                QMessageBox::critical(this, "Error", errorMsg);
        		exit(1);
        	}
        
        	if (listen(m_sockListen, SOMAXCONN) == SOCKET_ERROR)
        	{
                QString errorMsg = QStringLiteral("Listening socket failed. Winsock error: %1").arg(WSAGetLastError()) ;
                QMessageBox::critical(this, "Error", errorMsg);
        		exit(1);
        	}
        
        	serverPtr = this;
        }
        
        void Server::ServerRunning()
        {
            for (int i = 0; i < 100; i++)
            {
                ListenNewConnections();
            }
        }
        
        1 Reply Last reply
        0
        • P Offline
          P Offline
          pip010
          wrote on last edited by
          #4

          well you need 2 threads, one for the server but also 1 for the client. I can assume listen is blocking?
          also are you mixing Qt and native code? why? why not use Qt connectivity instead of raw socket api?

          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