Russian Qt Forum
Ноябрь 21, 2024, 22:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: многопоточный сервер qudpsocket  (Прочитано 2827 раз)
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« : Август 22, 2021, 15:01 »

Здравствуйте решил написать многопоточный сервер на qudpsocket
для начала задача проста сервер принимает сообщение от клиента в основном потоке, потом запускает qrunable из пула потока и шлет ответное сообщение в таске
вот код
main.cpp
Код
C++ (Qt)
#include <QCoreApplication>
#include "udpserver.h"
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   udpserver serv;
  // serv.startserver();
   return a.exec();
}
 
 

udpserver.h
Код
C++ (Qt)
#ifndef UDPSERVER_H
#define UDPSERVER_H
 
#include <QObject>
#include "mytask.h"
#include <QUdpSocket>
#include <QThreadPool>
#include <QDebug>
class udpserver : public QObject
{
   Q_OBJECT
public:
   explicit udpserver(QObject *parent = 0);
   QUdpSocket *servsock=nullptr;
public slots:
   void startserver();
   void readyreadclient();
};
 
udpserver.cpp
Код
C++ (Qt)
#include "udpserver.h"
 
udpserver::udpserver(QObject *parent) : QObject(parent)
{
   servsock=new QUdpSocket();
   servsock->bind(QHostAddress("127.0.0.1"),43620,QUdpSocket::ReuseAddressHint);
   connect(servsock,SIGNAL(readyRead()),this,SLOT(readyreadclient()));
 
}
 
 
void udpserver::startserver()
{
 
}
 
void udpserver::readyreadclient()
{
   while (servsock->hasPendingDatagrams())
   {
       QByteArray sb;
       quint64 size=servsock->pendingDatagramSize();
       sb.resize(size);
       QHostAddress adrcli;
       quint16 portcli;
       servsock->readDatagram(sb.data(),size,&adrcli,&portcli);
       qDebug()<<sb;
 
       int desc=servsock->socketDescriptor();
       mytask *mt=new mytask(adrcli,portcli,desc);
 
       mt->setAutoDelete(true);
       QThreadPool::globalInstance()->start(mt);
   }
}
 
mytask.h

Код
C++ (Qt)
#ifndef MYTASK_H
#define MYTASK_H
 
#include <QObject>
#include <QRunnable>
#include <QHostAddress>
#include <QUdpSocket>
class mytask : public QObject, public QRunnable
{
   Q_OBJECT
public:
   explicit mytask(QHostAddress,quint16,int,QObject *parent = nullptr);
   ~mytask();
   QHostAddress adressclient;
   quint16 portcli;
   QUdpSocket *sockrab;
   int nativdesc;
 
signals:
 
public slots:
 
protected:
   void run();
};
 
#endif // MYTASK_H
 

mytask.cpp
Код
C++ (Qt)
#include "mytask.h"
 
mytask::mytask(QHostAddress adrcl,quint16 pt,int dsc,QObject *parent) : QObject(parent)
{
   adressclient=QHostAddress(adrcl);
   portcli=pt;
   nativdesc=dsc;
}
mytask::~mytask()
{
   if (sockrab)
   {
       sockrab->deleteLater();
   }
}
 
void mytask::run()
{
   sockrab=new QUdpSocket();
   sockrab->setSocketDescriptor(nativdesc);
   QByteArray sb="OT SERVER PRIVET";
   quint64 sz=sb.size();
   sockrab->writeDatagram(sb,sb.size(),adressclient,portcli);
 
}
 


С клиента я посылаю сообщение потом жду ответа от сервера а затем клиент завершает работу
Проблема заключается в том что когда выполняется
Код
C++ (Qt)
  if (sockrab)
   {
       sockrab->deleteLater();
   }
 
по логике это вроде правильно чтобы не было утечек
но со временем сервер просто перестает отвечать
Код
C++ (Qt)
QSocketNotifier: Invalid socket 6 and type 'Read', disabling...
 
в случае если этот блок кода убрать то сервер работает нормально
как можно решить данную проблему? qt 4.8
« Последнее редактирование: Август 22, 2021, 15:05 от koldun90 » Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #1 : Август 23, 2021, 22:12 »

какаято ересь с передачей дескриптора слушающего сокета
передавай ответ через новый qudpsocket
Записан
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« Ответ #2 : Август 25, 2021, 17:58 »

Через новый udpsocket не получается передать. Клиенту ничего не приходит. Приходится делать setsocketdescriptor.
Клиент соединяется с сервером udp через connect to host
Записан
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« Ответ #3 : Август 25, 2021, 19:14 »

на клиентской части сделал bind сокета 127.0.0.1 порт на выбор ос поставил 0
bind->(127.0.0.1,0)

также на клиенте не делаю теперь connecttohost
а просто в начале работы делаю writedatagram

до этого на клиенте я вообще не биндил адресс
а связь устанавливал с помощью connecttohost и тольок потом отправлял датаграму
в итоге сервак принимал но в отдельном потоке когда я создавал новый qudpsocket и пытался отправить клиенту на адрес и порт клиенту сообщение не приходило не испускался у него readyread
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #4 : Август 25, 2021, 22:45 »

Через новый udpsocket не получается передать.

очень непонятно, я именно так и делаю при передачи
без какого либо connecttohost или bind
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.178 секунд. Запросов: 22.