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

Loop running with Qt running on side

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 942 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