Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: lkr в Aug 19, 2009, 20:53



Титла: Qt QLocalServer problem
Публикувано от: lkr в Aug 19, 2009, 20:53
Някой има ли идея в примерите с localfortune client/server как може да се чете от страна на сървъра, използвам следния код при newConnection() сигнал, но size-а винаги е 0.

Код
GeSHi (C++):
  1. void Server::readIt()
  2. {
  3.    QLocalSocket *socket = server->nextPendingConnection();
  4.    QDataStream in(socket);
  5.    in.setVersion(QDataStream::Qt_4_0);
  6.    quint16 blockSize = 0;
  7.  
  8.    if (blockSize == 0) {
  9.        if (socket->bytesAvailable() < (int)sizeof(quint16))
  10.            return;
  11.        in >> blockSize;
  12.    }
  13.  
  14.    if (in.atEnd())
  15.        return;
  16.  
  17.    QString nextFortune;
  18.    in >> nextFortune;
  19.  
  20.    qDebug() << nextFortune;
  21. }
  22.  

Изпращането става с:

Код
GeSHi (C++):
  1. void Client::sendIt()
  2. {  
  3.    socket->connectToServer(hostLineEdit->text());
  4.    QByteArray block;              
  5.    QDataStream out(&block, QIODevice::WriteOnly);
  6.    out.setVersion(QDataStream::Qt_4_0);
  7.    out.setDevice(socket);
  8.    out << (quint16)0;
  9.    out << tr("blaaaaa");
  10.    out.device()->seek(0);
  11.    out << (quint16)(block.size() - sizeof(quint16));
  12.  
  13.    socket->write(block);
  14.    socket->flush();
  15.    socket->disconnectFromServer();
  16. }
  17.  


Титла: Re: Qt QLocalServer problem
Публикувано от: dvasilev в Aug 19, 2009, 21:41
@lkr: Пропуснал си една итерация. Правиш опит да четеш при newConnection, което е грешка. Всъщност при този сигнал само трябва да инициализираш socket-а. Трябва да четеш, когато съответния QLocalSocket получен при newConnection изпрати readReady сигнал. В момента четеш от socket-а още преди да е получил данните и затова се получава така.

Отделен е въпросът, че в примера, който се опитваш да модифицираш blockSize се използва за проверка на това дали са получени всичките данни. Нещо, което при теб не се проверява. Както замисли се какъв е смисълът на ред 8 в сървърното приложение при наличие на ред 6. Най-вероятно компилатора ще го оптимизира, но все пак.


Титла: Re: Qt QLocalServer problem
Публикувано от: lkr в Aug 19, 2009, 21:47
Дори когато взема сокета с nextPendingConnection() и задам connect(socket, SIGNAL(readReady()), this, SLOT(read_that())) ефектът е същия.


Титла: Re: Qt QLocalServer problem
Публикувано от: dvasilev в Aug 19, 2009, 21:52
@lkr: Дай да видим това read_that какво прави, тъй като поне при това закачане към слот-а не знам по какъв начин той разбира от кой localSocket да чете.


Титла: Re: Qt QLocalServer problem
Публикувано от: lkr в Aug 19, 2009, 21:58
Оправих се, явно предния път при закачане към слота е имало друг проблем.

Код
GeSHi (C++):
  1. void Server::read_that()
  2. {
  3.    QDataStream in(socket);
  4.    in.setVersion(QDataStream::Qt_4_0);
  5.    quint16 blockSize = 0;
  6.  
  7.    if (blockSize == 0) {
  8.        if (socket->bytesAvailable() < (int)sizeof(quint16))
  9.            return;
  10.        in >> blockSize;
  11.    }
  12.  
  13.    if (in.atEnd())
  14.        return;
  15.  
  16.    QString nextFortune;
  17.    in >> nextFortune;
  18.  
  19.    qDebug() << nextFortune;
  20. }
  21.  
  22. void Server::readIt()
  23. {
  24.    socket = server->nextPendingConnection();
  25.    connect(socket, SIGNAL(readyRead()), this, SLOT(read_that()));
  26. }
  27.  


Титла: Re: Qt QLocalServer problem
Публикувано от: dvasilev в Aug 19, 2009, 22:11
@lkr: Тази схема няма да работи, когато към сървъра се закачат няколко клиента, които предават едновременно информация към него, тъй като всяко от връзките ще има отделен localSocket. За да се справиш с този проблем на read_that като параметър трябва да предаваш socket-а. В  тази ситуация закачането на този сигнал към readReady е малко по-сложно, но на помощ идва QSignalMapper.


Титла: Re: Qt QLocalServer problem
Публикувано от: lkr в Aug 19, 2009, 22:12
Но на мен не ми трябва да работи с няколко клиента :) Благодаря все пак.