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

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 ... 17 18 [19] 20 21
271  Qt / Работа с сетью / Re: Завершение серверного потока : Октябрь 20, 2011, 11:43
Так да оттуда, не хочется изобретать велосипед!) то что там описано: подключение клиентов в отдельном потоке реализовано и у меня, и это работает! Я же ничего не менял глобально.. а вот отключение клиентов и завершение работы этих потоков там не приводится, писал сам! Может в этом проблема.. Что вообще эта ошибка означает??
272  Qt / Работа с сетью / Re: Завершение серверного потока : Октябрь 20, 2011, 11:20
К сожалению не помогло..Даже наоборот, если убрать this, при закрытии приложения процесс остается висеть и грузить дико проц! Кину весь файл, глянь пожалуйста, может заметишь где собака зарыта)

Код:
FortuneServer::FortuneServer() : QTcpServer()
 {
     fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
              << tr("You've got to think about tomorrow.")
              << tr("You will be surprised by a loud noise.")
              << tr("You will feel hungry again in another hour.")
              << tr("You might have mail.")
              << tr("You cannot kill time without injuring eternity.")
              << tr("Computers are not intelligent. They only think they are.");
 
numCl = 0;
 }

bool FortuneServer::InitializeServer(int port)
{
QString nP;
nP.setNum(port);
nPort = port;
if (!listen(QHostAddress::Any, nPort)) {
           QMessageBox::critical(0,"Server Error","Unable to start the server");
           return false;
          }
emit MessageS("TCP-Server is listen <b>Port</b> " + nP,2);
return true;
}


void FortuneServer::incomingConnection(int socketDescriptor)
 {
    
QString fortune = fortunes.at(qrand() % fortunes.size());
     FortuneThread *thread = new FortuneThread(socketDescriptor, fortune, this);
connect(thread, SIGNAL(msgToGUI(QString,int)), SIGNAL(MessageS(QString,int)));
thread->numCl = ++numCl;
     connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

     thread->start();
 }

// ================================= Thread() ============================================================
// конструктор !
FortuneThread::FortuneThread(int socketDescriptor, const QString &fortune, QObject *parent)
     : QThread(parent), socketDescriptor(socketDescriptor), text(fortune), tcpSocket(NULL)
{
     connect(this, SIGNAL(MessageClient(QTcpSocket*,QString,int)),SLOT(sendToClient(QTcpSocket*,QString,int)));
flag = false;
numCl = 0;
}

void FortuneThread::run()
 {
headl objHead;
     IDThr = (int)currentThreadId();

     tcpSocket = new QTcpSocket(this);

     if(!tcpSocket->setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket->error());
        emit MessageClient(tcpSocket, "<b>SERVER:</b>Error to initialization Socket!",2);
}
    
        emit MessageClient(tcpSocket, "<b>SERVER:</b>Client was connected!",2);
   emit msgToGUI(QTime::currentTime().toString()+" <b>Client</b> " + QString().setNum(numCl) + " CONNECTED!",2);


while(!tcpSocket->waitForReadyRead(1))
 {
     if(tcpSocket->state() == QAbstractSocket::UnconnectedState) {
   emit msgToGUI("<b>Client</b> DISCONNECTED!",2);
 delete tcpSocket;
 
 return;
  }
 }

QFile file("MatrixData_" + QString().setNum(IDThr));
if(file.open(QIODevice::WriteOnly))
 {
   while(true)
    {
 
  if(tcpSocket->state() == QAbstractSocket::UnconnectedState) {
     if(file.isOpen()) file.close();
 emit msgToGUI("<b>Client</b> DISCONNECTED!",2);
 delete tcpSocket;
   
 return;
  }

  if(tcpSocket->waitForReadyRead(1000))
    {
   if(!flag) // false
    {  
timer.start();
    retrRead = tcpSocket->read((char*)&objHead,sizeof(objHead)); // читаем переданную стуктуру!                                

if( retrRead == -1)  return;
if( retrRead ==  0)  return;
    }

   if(tcpSocket->bytesAvailable() != objHead.sizeData)
{
  flag = true;
      continue;
    }

   file.write(tcpSocket->read(objHead.sizeData));

   emit MessageClient(tcpSocket, "<b>\nSize file: </b>" + QString().setNum(objHead.sizeData) + " Byte", 2);
emit msgToGUI(QTime::currentTime().toString()+" <b>File is sent - </b>" +  QString().setNum(timer.elapsed(),10) + " ms",2);
                          
flag = false;
file.close();
 
  } // waitForReadyRead()
   } // while()
     } // if() file.open()
else
{   // если нельзя открыть файл
    msgToGUI("<b>Error</b> of the determination of the file!",2);
    return;
}
} // run()

void FortuneThread::sendToClient(QTcpSocket* pSocket, QString str, int num) // отправить Клиенту
{
    QByteArray  arrBlock;

headl objHeadSendCl;
objHeadSendCl.sizeData = str.size();

arrBlock.append((const char*)&objHeadSendCl, sizeof(objHeadSendCl));
arrBlock.append(str);
  
    pSocket->write(arrBlock);
}

Главная форма:

Код:
FormServ::FormServ(QWidget *parent) : QDialog(parent)
{
   setupUi(this); // инициализация формы

   editServ->setFocus();
   QRegExp regExp("[0-9]{1,5}"); // ограниченный ввод данных
   editServ->setValidator(new QRegExpValidator(regExp,this));
  
   connect(butServ, SIGNAL(clicked()), SLOT(lineEd_textPORT()));
  
   m_Serv = new FortuneServer;
  
   connect(m_Serv, SIGNAL(MessageS(QString,int)), SLOT(slotShowMessage(QString,int)));
};

void FormServ::lineEd_textPORT()
{
 bool ok;
      m_Serv->InitializeServer(editServ->text().toInt(&ok,10));
}

void FormServ::slotShowMessage(QString mess,int id)
{
if(id == 2) textEditServ->append(mess);
    
}
273  Qt / Работа с сетью / Re: Завершение серверного потока : Октябрь 20, 2011, 10:34
Сигнал msgToGUI() в принципе не связан с сокетом.. он просто выводит сообщение о дисконекте клиента на форму сервера!Но, если поменять ошибка все равно иногда проскакивает..  В замешательстве и именно, когда закрываешь приложение сервера, а не вовремя отключения/подключения клиентов или передаче файлов..! Непонимающий

// файл QObgect.cpp
QTread *QObject::thread() const
{
   return d_func()->threadData->thread;  // на этой строке вылетала ошибка !!!
}
274  Qt / Работа с сетью / Re: Завершение серверного потока : Октябрь 19, 2011, 11:27
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

Действительно это решило проблему! Огромное спасибо, andrew.k =)

Вроде все работает как и задумывалось.. Клиенты нормально подключаются в отдельных потоках и передают файлы на сервер, нормально и отключаются..! Теперь стоит вопрос в скорости и надежности, а именно:
1. Обнаруживать, что клиент отключился максимально быстро, даже в момент передачи файла и завершить корректно поток, связанный с этим клиентом! После определенного тестирования возникает такая проблемка (не всегда, но пару раз вылетала программа!!!)..
Если скажем 3 клиента передают одновременно файлы большого размера и в момент передачи закрыть одного из клиентов, то при завершении работы сервера вылитала ошибка в файле QObject.cpp:
Код:
QTread *QObject::thread() const
{
   return d_func()->threadData->thread;  // на этой строке вылетала ошибка !!!
}


Чтобы это значило?Непонимающий

2. Принимать файлы большого размера (около 200 Мб) также как можно быстрее! Если есть идеи как можно оптимизировать этот код, подскажите пожалуйста!

Код:
void FortuneThread::run()
 {
     headl objHead;
     IDThr = (int)currentThreadId();

     tcpSocket = new QTcpSocket(this);

     if(!tcpSocket->setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket->error());
        emit MessageClient(tcpSocket, "<b>SERVER:</b>Error to initialization Socket!",2);
}
    
        emit MessageClient(tcpSocket, "<b>SERVER:</b>Client was connected!",2);
   emit msgToGUI(QTime::currentTime().toString()+" <b>Client</b> " + QString().setNum(numCl) + " CONNECTED!",2);

   QFile file("MatrixData_" + QString().setNum(IDThr));
   if(file.open(QIODevice::WriteOnly))
    {
while(true)
{
if(tcpSocket->state() == QAbstractSocket::UnconnectedState) {
 delete tcpSocket;
 emit msgToGUI("<b>Client</b> DISCONNECTED!",2);
 
 return;
}

if(tcpSocket->waitForReadyRead(1000))
    {
 if(!flag) // false ; чтение заголовка
 {  
timer.start();
    retrRead = tcpSocket->read((char*)&objHead,sizeof(objHead)); // читаем переданную стуктуру!                                

if( retrRead == -1)  return;
if( retrRead ==  0)  return;
  }
 
     
      if(tcpSocket->bytesAvailable() != objHead.sizeData)
  {
    flag = true;
    continue;
  }

  file.write(tcpSocket->read(objHead.sizeData));

  emit MessageClient(tcpSocket, "<b>\nSize file: </b>" + QString().setNum(objHead.sizeData) + " Byte", 2);
  emit msgToGUI(QTime::currentTime().toString()+" <b>File is sent - </b>" + QString().setNum(timer.elapsed(),10) + " ms",2);
                          
  flag = false;
  file.close();
 
 
} // waitForReadyRead()
} // while()
       }
        else { // если нельзя прочитать файл
 msgToGUI("<b>Error</b> of the determination of the file!",2);
 return;
      }
}
275  Qt / Работа с сетью / Завершение серверного потока : Октябрь 18, 2011, 10:56
Доброго дня! Проблема в следующем..
Создаю на каждого подключаемого клиента свой поток
Код:
void FortuneServer::incomingConnection(int socketDescriptor)
 {
     
     QString fortune = fortunes.at(qrand() % fortunes.size());
     FortuneThread *thread = new FortuneThread(socketDescriptor, fortune, this);
     connect(thread, SIGNAL(msgToGUI(QString,int)), SIGNAL(MessageS(QString,int)));
     
     connect(thread, SIGNAL(finished()), SLOT(deleteLater()));

     thread->start();
 }

Функция потока:
Код:
void FortuneThread::run()
 {
     tcpSocket = new QTcpSocket(this); // для каждого подключенного клиента свой СОКЕТ

     if(!tcpSocket->setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket->error());
        emit MessageClient(tcpSocket, "<b>SERVER:</b>Error to initialization Socket!",2);
}
 
while(true)
{
             if(tcpSocket->state() == QAbstractSocket::UnconnectedState)
                     {
        tcpSocket->disconnectFromHost();
                tcpSocket->waitForDisconnected();
return;                                           // ??????!!!!!!!!!!         
       }

if(tcpSocket->waitForReadyRead(3000))
     {
// .... принимаем данные от клиента

     } // waitForReadyRead()

} // while()
}

Собственно вопрос как завершить правильно поток, если клиент отсоединился??! Ибо сейчас, если клиент отсоединился он больше не подключается (не вызывается incomingConnection) ! Если закоментить return, то клиент подключается, но начинает грузиться CPU!
276  Qt / 2D и 3D графика / Re: QMainWindow + OpenGL : Октябрь 12, 2011, 12:15
Что за форум, сам вопрос задаешь и сам же на него отвечаешь ((
Может кому пригодится, работает так:
Код:
class DrawOpenGL;
class ClientGL : public QMainWindow, public Ui::ClientGLClass
{
Q_OBJECT

public:
ClientGL(QWidget *parent = 0, Qt::WFlags flags = 0);
~ClientGL();

        DrawOpenGL *glWidget;
};

В конструкторе класса  ClientGL:
Код:
glWidget = new DrawOpenGL(widgetGL); // где widgetGL objectName виджета
widgetGL->setLayout(new QHBoxLayout);
widgetGL->layout()->addWidget(glWidget);

в методах initializeGL(); resizeGL(int nWidth, int nHeight); paintGL(); задаешь нужные параметры отрисовки OpenGL

Вот и все)
277  Qt / 2D и 3D графика / Re: QMainWindow + OpenGL : Октябрь 12, 2011, 09:33
Про ООП почитал бы для начала.

И, что конкретно мне о нем (ООП) почитать, что решит мой вопрос?
278  Qt / 2D и 3D графика / Re: QMainWindow + OpenGL : Октябрь 11, 2011, 16:54
void QMainWindow::setCentralWidget ( QWidget * widget )
А в дизайнере через "Promote to".

Если я правильно понял в конструкторе главного окна (QMainWindow) добавляем:

setCentralWidget(widgetGL); // где widgetGL objectName виджета

в дизайнере: правой кнопкой по Главному окну -> Promote to, где выбираем
"Base class name:" - QWidget
"Promoted class name:" - DrawOpenGL
"Header file:" - тот хедер, где описан DrawOpenGL

тем самым мы свяжем главное окно с виджетом? И функции
    virtual void initializeGL();
    virtual void resizeGL(int nWidth, int nHeight);
    virtual void paintGL();
должны вызываться автоматически при создании главного окна??? Или как оно должно работать?!
 
279  Qt / 2D и 3D графика / QMainWindow + OpenGL : Октябрь 11, 2011, 14:25
Доброго дня) Нужно отобразить графику OpenGL в главном окне Qt:
Класс главного окна:

Код:
class ClientGL : public QMainWindow, public Ui::ClientGLClass 
{
Q_OBJECT

public:
ClientGL(QWidget *parent = 0, Qt::WFlags flags = 0);
~ClientGL();
};

я так понимаю надо создать еще один класс:

Код:
class DrawOpenGL : public QGLWidget
{
Q_OBJECT

public:
DrawOpenGL();

protected:
    virtual void initializeGL();
    virtual void resizeGL(int nWidth, int nHeight);
    virtual void paintGL();

};

И этот класс каким-то образом увязать с главным окном.. вопрос КАК???!!!
Допустим разместить через Qt Desiner, например, объект QWidget и в него выводить.. можно?? Тогда каким образом, подскажите пожалуйста?! =)


280  Qt / Общие вопросы / Re: Создание WinAPI окна с Qt формы : Октябрь 07, 2011, 14:03
Или это у постановщика задачи фетиш такой: заставлять народ ежа с ужом скрещивать? Смеющийся

наверное))
281  Qt / Общие вопросы / Re: Создание WinAPI окна с Qt формы : Октябрь 07, 2011, 14:02
в общем работает так))

Код:
#include "servgl.h"
#include <QMessageBox.h>


HINSTANCE hInst;
static HGLRC hRC; // Постоянный контекст рендеринга
static HDC hDC; // Приватный контекст устройства GDI


bool RegisterClass(HINSTANCE hInstance);



ServGL::ServGL(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
setupUi(this);
connect(crWinGL, SIGNAL(clicked()), SLOT(slotCreateWindowGL()));

hInst = GetModuleHandle(NULL);
RegisterClass(hInst);
   
}

ServGL::~ServGL()
{
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
GLuint PixelFormat;
PAINTSTRUCT ps;

static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR), // Размер этой структуры
1, // Номер версии (?)
PFD_DRAW_TO_WINDOW |// Формат для Окна
PFD_SUPPORT_OPENGL |// Формат для OpenGL
PFD_DOUBLEBUFFER,// Формат для двойного буфера
PFD_TYPE_RGBA, // Требуется RGBA формат
32, // Выбор 16 бит глубины цвета
0, 0, 0, 0, 0, 0,// Игнорирование цветовых битов (?)
0, // нет буфера прозрачности
0, // Сдвиговый бит игнорируется (?)
0, // Нет буфера аккумуляции
0, 0, 0, 0, // Биты аккумуляции игнорируются (?)
32, // 16 битный Z-буфер (буфер глубины)  
0, // Нет буфера траффарета
0, // Нет вспомогательных буферов (?)
PFD_MAIN_PLANE, // Главный слой рисования
0, // Резерв (?)
0, 0, 0 // Маски слоя игнорируются (?)
};
switch (message) // Тип сообщения
{
case WM_CREATE:
hDC = GetDC(hWnd); // Получить контекст устройства для окна
PixelFormat = ChoosePixelFormat(hDC, &pfd);
// Найти ближайшее совпадение для нашего формата пикселов
if (!PixelFormat)
{
MessageBox(0,TEXT("Can't Find A Suitable PixelFormat."),TEXT("Error"),MB_OK|MB_ICONERROR);
PostQuitMessage(0);
// Это сообщение говорит, что программа должна завершится
break; // Предтовращение повтора кода
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
{
MessageBox(0,TEXT("Can't Set The PixelFormat."),TEXT("Error"),MB_OK|MB_ICONERROR);
PostQuitMessage(0);
break;
}
hRC = wglCreateContext(hDC);
if(!hRC)
{
MessageBox(0,TEXT("Can't Create A GL Rendering Context."),TEXT("Error"),MB_OK|MB_ICONERROR);
PostQuitMessage(0);
break;
}
if(!wglMakeCurrent(hDC, hRC))
{
MessageBox(0,TEXT("Can't activate GLRC."),TEXT("Error"),MB_OK|MB_ICONERROR);
PostQuitMessage(0);
break;
}
InitGL();
paintGL();
SwapBuffers( hDC );    // Меняем буфер (двойная буферизация)
break;

case WM_DESTROY:
    PostQuitMessage(0);
    break;

case WM_PAINT:
//
                break;


default:
       return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}

bool RegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;   // Структура класса Windows для установки типа окна
   
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
        wc.hInstance = hInst;
wc.hIcon = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("OpenGL WinClass");


if(!RegisterClass(&wc))
{
  MessageBox(0,TEXT("Failed To Register The Window Class."),TEXT("Error"),MB_OK|MB_ICONERROR);
  return false;
}

return true;
}


bool ServGL::slotCreateWindowGL()
{

     MSG msg;  // Структура сообщения Windows
HWND hWnd; // Сохранение дискриптора окна

hWnd = CreateWindow(TEXT("OpenGL WinClass"),
                    TEXT("OpenGL"), // Заголовок вверху окна
                    WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
                     200, 200, // Позиция окна на экране
                    640, 480, // Ширина и высота окна
                    NULL,
                    NULL,
                    hInst,
                    NULL
                   );

if(!hWnd)
{
  MessageBox(0,TEXT("Window Creation Error."),TEXT("Error"),MB_OK | MB_ICONERROR);
}

ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
SetFocus(hWnd);

while (1)
{
// Обработка всех сообщений
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
 {
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
return true;
}
 }
}
}
282  Qt / Общие вопросы / Re: Создание WinAPI окна с Qt формы : Октябрь 07, 2011, 09:55
Что делаешь и что не получается? Зачем вообще WinAPI юзать?

Задание такое дали.. Создать Qt форму на ней пару кнопок.. по нажатию на одной из них открывается WinAPI окошко, где будут рисоваться примитивы OpenGL!
283  Qt / Общие вопросы / Создание WinAPI окна с Qt формы : Октябрь 07, 2011, 09:47
Добрый день! Подскажите пожалуйста, как по нажатию на кнопку с формы Qt создать правильно WinAPI окно?
284  Qt / Общие вопросы / Re: Отключение компьютера : Сентябрь 13, 2011, 12:40
Вот, что нашел в инете..

Код:
int ShutdownWindows()
{
  HANDLE            hToken;
  LUID              takeOwnershipValue;
  TOKEN_PRIVILEGES  tkp;
  if (!OpenProcessToken(GetCurrentProcess(),
                        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    return 0;
  if (!LookupPrivilegeValue(0, SE_SHUTDOWN_NAME, &takeOwnershipValue))
    return 0;
  tkp.PrivilegeCount = 1;
  tkp.Privileges[0].Luid = takeOwnershipValue;
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  AdjustTokenPrivileges(hToken, false, &tkp, sizeof(TOKEN_PRIVILEGES), 0, 0);
  if (GetLastError())
    return 0;
 
  return ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN,0);
}


И это работает Смеющийся
285  Qt / Общие вопросы / Re: Отключение компьютера : Сентябрь 13, 2011, 11:52
а какие библиотеки нужно подключить для работы с WinAPI Непонимающий
Страниц: 1 ... 17 18 [19] 20 21

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