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

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

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Помогите с сервером....  (Прочитано 17475 раз)
lolbla2
Гость
« Ответ #30 : Февраль 25, 2012, 18:15 »

Спасибо, а что в методе run в потоке делать?

ничего. не перегружай поток, а используй стандартный QThread

спасибо вроде сделал, посмотри пожалуйста норм вышло?

replyer.h, replyer.cpp
Код
C++ (Qt)
#include <QObject>
#include <QtNetwork>
#include <QDebug>
 
class Replyer : public QObject
{
   Q_OBJECT
public:
   explicit Replyer(QObject *parent = 0);
 
private:
       QList<QTcpSocket*> mClients;
       void reply(QString message);
       QString text;
       int blockSize;
 
 
public slots:
       void newConnection(int descriptor);
       void newDisconnection(); //смешное  название получилось :)
 
private slots:
       void readData();
 
};
 
 
#include "replyer.h"
 
Replyer::Replyer(QObject *parent) :
   QObject(parent)
{
   blockSize = 0;
}
 
void Replyer::newConnection(int descriptor)
{
           QTcpSocket *client = new QTcpSocket(this);
           if(client->setSocketDescriptor(descriptor))
           {
                   connect(client, SIGNAL(readyRead()), SLOT(readData()));
                   connect(client,SIGNAL(disconnected()),SLOT(newDisconnection()));
                   mClients.append(client);
           }
           else
           {
                   client->deleteLater();
           }
}
void Replyer::newDisconnection()
{
 
   foreach(QTcpSocket *client, mClients)
   {
       if (client->state()!=QAbstractSocket::ConnectedState)
           {
              qDebug() << client->socketDescriptor() << " Client Disconnected";
              mClients.removeOne(client);
              client->deleteLater();
           }
   }
}
 
void Replyer::readData()
{
   QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
 
   QString message;
        while(client->bytesAvailable())
      {
          QDataStream in(client);
        in.setVersion(QDataStream::Qt_4_7);
 
        if (blockSize == 0) {
          if (client->bytesAvailable() < (int)sizeof(quint32))
              return;
        in >> blockSize;
      }
 
      if (client->bytesAvailable() < blockSize)
        return;
 
        in>>message;
       }
   blockSize = 0;
   text = message;
   qDebug() << message;
   reply(message);
}
 
void Replyer::reply(QString message)
{
   QByteArray block;
   QDataStream out(&block, QIODevice::WriteOnly);
   out.setVersion(QDataStream::Qt_4_7);
   out << (quint32)0;
   out << message;
   out.device()->seek(0);
   out << (quint32)(block.size() - sizeof(quint32));
   foreach(QTcpSocket* client, mClients)
     {
         client->write(block);
     }
}
 

MyServerh, MyServer.cpp
Код
C++ (Qt)
#include <QtNetwork/QTcpServer>
#include <QDebug>
#include "replyer.h"
 
class MyServer : public QTcpServer
{
   Q_OBJECT
public:
   explicit MyServer(QObject *parent = 0);
   void StartServer();
protected:
   void incomingConnection(int socketDescriptor);
signals:
   void newClient(int socketDescriptor);
private:
   Replyer *replyer;
};
 
#include "myserver.h"
 
MyServer::MyServer(QObject *parent) :
   QTcpServer(parent)
{
   replyer = new Replyer();
   connect(this, SIGNAL(newClient(int)), replyer, SLOT(newConnection(int)));
   QThread *thread = new QThread(this);
   connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
   replyer->moveToThread(thread);
   thread->start();
}
 
void MyServer::incomingConnection(int socketDescriptor)
{
   qDebug() << socketDescriptor << " Client Connected";
   emit newClient(socketDescriptor);
}
 
void MyServer::StartServer()
{
   if(!this->listen(QHostAddress::Any,1234))
   {
       qDebug() << "Could not start server";
 
   }
   else
   {
       qDebug() << "Listening...";
   }
}
 
« Последнее редактирование: Февраль 25, 2012, 18:18 от lolbla2 » Записан
mutineer
Гость
« Ответ #31 : Февраль 25, 2012, 18:29 »

вроде должно работать. вот только читаешь ты все куски данных в один массив, так что если несколько клиентов одновременно пришлют данные, то их данные тупо смешаются
Записан
lolbla2
Гость
« Ответ #32 : Февраль 25, 2012, 19:29 »

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

Хмм... кстати я тоже об этом думал, но когда пытался быстро слать от 2 клиентов сообщения с разных компов, то вроде всё норм, но вроде бы потенциально может прийти клиентам какая-нибудь фигня смешанная. А как эту проблему пофиксить? Завести какую-то очередь сообщений что ли?

то есть клиент прислал сообщение его в очередь, а потом пока очередь не пуста отсылать эти сообщения клиентам, может так ?
Записан
mutineer
Гость
« Ответ #33 : Февраль 25, 2012, 20:23 »

Да просто заведи на каждого клиента свой blockSize
Записан
lolbla2
Гость
« Ответ #34 : Февраль 25, 2012, 20:27 »

Да просто заведи на каждого клиента свой blockSize

а идея с очередью не катит?)
Записан
mutineer
Гость
« Ответ #35 : Февраль 25, 2012, 20:28 »

Да просто заведи на каждого клиента свой blockSize

а идея с очередью не катит?)

Не знаю, имхо излишне, хеша вида <сокет, blockSize> хватит с головой. Но можешь попробовать и очередь:)
Записан
lolbla2
Гость
« Ответ #36 : Февраль 25, 2012, 20:32 »

Да просто заведи на каждого клиента свой blockSize

а идея с очередью не катит?)

Не знаю, имхо излишне, хеша вида <сокет, blockSize> хватит с головой. Но можешь попробовать и очередь:)

сделал очередь, но не знаю как проверить работает ли...
Записан
mutineer
Гость
« Ответ #37 : Февраль 25, 2012, 20:46 »

И я не знаю. Это ж вероятная ситуация. Вызвать ее специально довольно сложно. проблема у тебя даже не в перемешивании данных, а в том, что blockSize ты прочитаешь из одного сокета, потом выйдешь из функции, а в следующий раз зайдешь уже когда сигнал будет от другого сокета и читать будешь уже не то, что ожидал
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #38 : Сентябрь 17, 2012, 14:52 »

Но это только для 1-ого клиента  Улыбающийся
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


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