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