Russian Qt Forum
Июнь 15, 2024, 23:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Помогите с сервером....  (Прочитано 17476 раз)
lolbla2
Гость
« : Февраль 23, 2012, 17:14 »

Вообщем сервер рассылает данные в отдельный поток...

myserver.cpp
Код
C++ (Qt)
#include "myserver.h"
 
MyServer::MyServer(QObject *parent) :
   QTcpServer(parent)
{
}
 
 
void MyServer::StartServer()
{
   if(!this->listen(QHostAddress::Any,1234))
   {
       qDebug() << "Could not start server";
       thread = new MyThread(this);
       connect(thread, SIGNAL(finished()),thread, SLOT(deleteLater()));
       thread->start();
   }
   else
   {
       qDebug() << "Listening...";
   }
}
 
void MyServer::incomingConnection(int socketDescriptor)
{
   qDebug() << socketDescriptor << " Connecting...";
   thread->newConnection(socketDescriptor);
 
}
 

Mythread.cpp
Код
C++ (Qt)
#include "mythread.h"
 
MyThread::MyThread( QObject *parent) :
   QThread(parent)
{
   blockSize = 0;
//    socket = new QTcpSocket(this);
}
 
void MyThread::run()
{
   //thread starts here
   qDebug() <<  " Starting thread";
//    socket = new QTcpSocket();
//    if(!socket->setSocketDescriptor(this->socketDescriptor))
//    {
//        emit error(socket->error());
//        return;
//    }
 
//    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
//    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
//    sockets.append(socket);
//    qDebug() << socketDescriptor << " Client Connected";
 
   exec();
}
void MyThread::newConnection(int sockDesc)
{
   qDebug() << sockDesc << " Client Connected";
   QTcpSocket *socket = new QTcpSocket();
   if(!socket->setSocketDescriptor(sockDesc))
      {
          emit error(socket->error());
          return;
      }
 connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);// падает тут
   connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
   sockets.append(socket);
 
 
 
}
 
void MyThread::readyRead()
{
 
    QString message;
    for(int i=0; i<sockets.size(); i++)
     {
         while(sockets[i]->bytesAvailable())
       {
           QDataStream in(sockets[i]);
         in.setVersion(QDataStream::Qt_4_7);
 
         if (blockSize == 0) {
           if (sockets[i]->bytesAvailable() < (int)sizeof(quint32))
               return;
         in >> blockSize;
       }
 
       if (sockets[i]->bytesAvailable() < blockSize)
         return;
 
         in>>message;
        }
    blockSize=0;
    }
    text = message;
    qDebug() << socketDescriptor << " Data in: " << message;
    SendData();
}
 
void MyThread::disconnected()
{
   for (int i=0; i<sockets.size(); i++)
               if (sockets[i]->state()!=QAbstractSocket::ConnectedState)
               {
                   qDebug() << sockets[i]->socketDescriptor() << "Disconnected";
                   sockets[i]->deleteLater();
                   sockets.removeAt(i);
               }
   if(sockets.empty())
     exit(0);
}
void MyThread::SendData()
{
   QByteArray block;
   QDataStream out(&block, QIODevice::WriteOnly);
   out.setVersion(QDataStream::Qt_4_7);
   out << (quint32)0;
   out << text;
   out.device()->seek(0);
   out << (quint32)(block.size() - sizeof(quint32));
   for(int i=0; i<sockets.size(); i++)
       sockets[i]->write(block);
}
 

Не могу понять, в закомменченной строке "падает тут" происходит ошибка сегментации SEGSIG fault, вроде для сокета память выделена и для потока, в чём же дело?
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #1 : Февраль 23, 2012, 17:23 »

У тебя после ошибки "Could not start server" создаётся поток чтения, а если ошибки нет, то он не создаётся. По-мойму тут что-то должно быть наоборот Улыбающийся
Записан
mutineer
Гость
« Ответ #2 : Февраль 23, 2012, 17:29 »

Непонятно зачем тебе поток - все у тебя происходит в главном потоке, а дополнительный просто eventLoop гоняет

Да и сокет в случае ошибки ты тож не удаляешь - так и висит он в утекшей памяти))
Записан
lolbla2
Гость
« Ответ #3 : Февраль 23, 2012, 18:24 »

Непонятно зачем тебе поток - все у тебя происходит в главном потоке, а дополнительный просто eventLoop гоняет

Да и сокет в случае ошибки ты тож не удаляешь - так и висит он в утекшей памяти))

Отдельный поток только в run ? а то что просто поток гоняется и если кто-то подключился обрабатывается...
Записан
mutineer
Гость
« Ответ #4 : Февраль 23, 2012, 19:19 »

Отдельный поток только в run ? а то что просто поток гоняется и если кто-то подключился обрабатывается...

Сейчас вся обработка сигналов от сокета происходит в том же потоке, в котором крутится сервер
Записан
lolbla2
Гость
« Ответ #5 : Февраль 23, 2012, 19:30 »

Отдельный поток только в run ? а то что просто поток гоняется и если кто-то подключился обрабатывается...

Сейчас вся обработка сигналов от сокета происходит в том же потоке, в котором крутится сервер

почему? типо отдельный поток только в методе run? а класс QThread на самом деле не весь в отдельном потоке?
Записан
mutineer
Гость
« Ответ #6 : Февраль 23, 2012, 19:34 »

Ага, QThread - это просто класс, управляющий потоком. В новом треде выполняется только метод run() и все, что вызвано из него непосредственно
Записан
lolbla2
Гость
« Ответ #7 : Февраль 23, 2012, 20:13 »

Ага, QThread - это просто класс, управляющий потоком. В новом треде выполняется только метод run() и все, что вызвано из него непосредственно

Ладно, хорошо тогда принимать буду в основном потоке, а рассылать хочу всем клиентам в отдельном потоке пытаюсь это сделать следующим образом:

Myserver.cpp
Код
C++ (Qt)
#include "myserver.h"
 
MyServer::MyServer(QObject *parent) :
   QTcpServer(parent)
{
   client = new QTcpSocket();
   blockSize = 0;
}
 
 
void MyServer::StartServer()
{
   if(!this->listen(QHostAddress::Any,1234))
   {
       qDebug() << "Could not start server";
 
   }
   else
   {
       qDebug() << "Listening...";
   }
}
 
void MyServer::incomingConnection(int socketDescriptor)
{
   qDebug() << socketDescriptor << " Connecting...";
       if(!client->setSocketDescriptor(socketDescriptor))
       {
//            emit error(client->error());
           return;
       }
 
       connect(client,SIGNAL(readyRead()),this,SLOT(ReceiveData()),Qt::DirectConnection);
       connect(client,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
       sockets.append(client);
       qDebug() << socketDescriptor << " Client Connected";
}
void MyServer::ReceiveData()
{
   QString message;
   for(int i=0; i<sockets.size(); i++)
    {
        while(sockets[i]->bytesAvailable())
      {
          QDataStream in(sockets[i]);
        in.setVersion(QDataStream::Qt_4_7);
 
        if (blockSize == 0) {
          if (sockets[i]->bytesAvailable() < (int)sizeof(quint32))
              return;
        in >> blockSize;
      }
 
      if (sockets[i]->bytesAvailable() < blockSize)
        return;
 
        in>>message;
       }
   blockSize=0;
   }
   text = message;
   qDebug() <<  " Data in: " << message;
   thread = new MyThread(sockets, text);
   connect(thread, SIGNAL(finished()),thread, SLOT(deleteLater()));
   thread->start();
}
void MyServer::disconnected()
{
   for (int i=0; i<sockets.size(); i++)
               if (sockets[i]->state()!=QAbstractSocket::ConnectedState)
               {
                   qDebug() << sockets[i]->socketDescriptor() << "Disconnected";
                   sockets[i]->deleteLater();
                   sockets.removeAt(i);
               }
}
 

MyThread.cpp
Код
C++ (Qt)
#include "mythread.h"
 
MyThread::MyThread(QList <QTcpSocket *> clients, QString mes, QObject *parent) :
   QThread(parent)
{
   sockets = clients;
   text = mes;
}
 
void MyThread::run()
{
   //thread starts here
   qDebug() <<  " Starting thread";
   if(sockets.isEmpty())
       exit(0);
   QByteArray block;
   QDataStream out(&block, QIODevice::WriteOnly);
   out.setVersion(QDataStream::Qt_4_7);
   out << (quint32)0;
   out << text;
   out.device()->seek(0);
   out << (quint32)(block.size() - sizeof(quint32));
   for(int i=0; i<sockets.size(); i++)
       sockets[i]->write(block);
   exec();
}
 

в итоге получаю:

Listening...
264  Connecting...
264  Client Connected
 Data in:  "fgd"
 Starting thread
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x5d4d48), parent's thread is QThread(0x5d2e28), current thread is MyThread(0x5d6458)
Записан
mutineer
Гость
« Ответ #8 : Февраль 23, 2012, 20:22 »

ты создал сокет в одном потоке, а используешь в другом. Внутренние объекты сокета противятся такому.

да и идея создать один сокет, а потом засовывать его в массив несколько раз, как будто их много, тоже не особо хороша
« Последнее редактирование: Февраль 23, 2012, 20:23 от mutineer » Записан
lolbla2
Гость
« Ответ #9 : Февраль 23, 2012, 20:32 »

ты создал сокет в одном потоке, а используешь в другом. Внутренние объекты сокета противятся такому.

да и идея создать один сокет, а потом засовывать его в массив несколько раз, как будто их много, тоже не особо хороша

а как же мне тогда в отдельном потоке разослать всем клиентам данные?
Записан
mutineer
Гость
« Ответ #10 : Февраль 23, 2012, 21:04 »

Ну например можно мувнуть сокет в нужный тред. Или создать его прям в нужном треде

ну и еще - тред у тебя не умрет никогда, а на каждую новую порцию данных будет создан новый
« Последнее редактирование: Февраль 23, 2012, 21:10 от mutineer » Записан
fuCtor
Гость
« Ответ #11 : Февраль 24, 2012, 14:39 »

А может посмотреть на существующие решения в плане организации межпроцессного общения и соответствующим протоколам?
Либо сервер должен в само приложения встраиваться наряду с клиентом?
Записан
lolbla2
Гость
« Ответ #12 : Февраль 24, 2012, 14:52 »

А может посмотреть на существующие решения в плане организации межпроцессного общения и соответствующим протоколам?
Либо сервер должен в само приложения встраиваться наряду с клиентом?
Можно ссылки по этому поводу пожалуйста...?

Не совсем понял вопрос. Клиент отдельно, сервер отдельно. Сервер принимает данные от какой-нибудь клиента и отсылает их всем клиентам. То есть он нужен чтобы разослать данные от каждого клиента каждому клиенту, т.е. для взаимодействия клиентов каждый с каждым.
Записан
lolbla2
Гость
« Ответ #13 : Февраль 24, 2012, 14:54 »

Ну например можно мувнуть сокет в нужный тред. Или создать его прям в нужном треде

ну и еще - тред у тебя не умрет никогда, а на каждую новую порцию данных будет создан новый

Имеешь в виду для каждого сокета отдельный поток что ли? Типо сокет подключился, создали для него поток... Я то хотел один поток для передачи всем сокетам (клиентам), поэтому в поток передаю список клиентов.  Кстати почему-то лист клиентов нельзя мувнуть в поток... почему? Чот я до конца не пойму, это получается поток может использовать только объекты созданные внутри него или как ?
Записан
mutineer
Гость
« Ответ #14 : Февраль 24, 2012, 16:18 »

Ну например можно мувнуть сокет в нужный тред. Или создать его прям в нужном треде

ну и еще - тред у тебя не умрет никогда, а на каждую новую порцию данных будет создан новый

Имеешь в виду для каждого сокета отдельный поток что ли? Типо сокет подключился, создали для него поток... Я то хотел один поток для передачи всем сокетам (клиентам), поэтому в поток передаю список клиентов.  Кстати почему-то лист клиентов нельзя мувнуть в поток... почему? Чот я до конца не пойму, это получается поток может использовать только объекты созданные внутри него или как ?

что значит "мувнуть лист клиентов"?
нет, поток может и другие объекты использовать, но родитель объекта и сам объект должны находиться в одном и том же потоке

можно и один поток на весь список клиентов, просто лучше сокеты для этих клиентов прям в потоке создавать. Кстати, сокет у тебя сейчас только один, независимо от количества клиентов, что неправильно
« Последнее редактирование: Февраль 24, 2012, 16:22 от mutineer » Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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