Loop running with Qt running on side



  • 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);
    }
    
    


  • 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.



  • 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();
        }
    }
    


  • 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?


Log in to reply