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

  • Moderators

    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
 

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