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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: TcpServer не принимает сообщения  (Прочитано 6793 раз)
RedDog
Гость
« : Декабрь 09, 2010, 10:07 »

не пойму, почему не доходят сообщения до сервера:
вот сам сервер:
Код:
class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QTcpServer *server;
    QTcpSocket *serverSocket;
    Ui::Dialog *ui;
private slots:
    void on_serverConnect();
    void on_dataRead();
};

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    server = new QTcpServer(this);
    connect(server, SIGNAL(newConnection()), this, SLOT(on_serverConnect()));
    server->listen(QHostAddress::Any, 3355);
}

void Dialog::on_serverConnect()
{
    serverSocket = server->nextPendingConnection();
    connect(serverSocket, SIGNAL(readyRead()), this, SLOT(on_dataRead()));
    QTextCursor curs = ui->textEdit->textCursor();
    curs.movePosition(QTextCursor::End);
    curs.insertText("Connected!\r\n");
}

void Dialog::on_dataRead()
{
    QByteArray readingData;
    while(serverSocket->isReadable())
        readingData.append(serverSocket->readAll());
    QTextCursor curs = ui->textEdit->textCursor();
    curs.movePosition(QTextCursor::End);
    curs.insertText(readingData);
}
подключение происходит (т.е. слот on_serverConnect срабатывает, правда в дебаге с почему то раза 2-3 на брейкпоинте останавливается)

подключаюсь и отправляю ему сообщения вот так:

Код:
CServerConnection::CServerConnection(QObject *parent) :
    QObject(parent)
{
    connection = new QTcpSocket(this);
    connection->connectToHost("localhost", 3355, QIODevice::ReadWrite);
    connection->waitForConnected();
}

void CServerConnection::SendData(QByteArray data)
{
    if (!connection->isOpen())
        return;
    connection->write(QByteArray("Test String"));
    connection->flush();
}
Записан
BRE
Гость
« Ответ #1 : Декабрь 09, 2010, 10:15 »

Что, по твоему делает этот код?
Код
C++ (Qt)
void Dialog::on_dataRead()
{
   while(serverSocket->isReadable())
       readingData.append(serverSocket->readAll());
}
 

Почему не почмотреть примеры и не разобраться как они работают, почему не почитать документацию?  Улыбающийся
Записан
RedDog
Гость
« Ответ #2 : Декабрь 09, 2010, 11:40 »

Благодарю за наводку, принимает.
Теперь другая проблема, в цикле шлю сообщения со структурой, принимает не пойми как, т.е. большая часть данных где то теряется, при чем именно пакеты целиком теряются, т.к выводит правильные значения, но всего 2-3 штуки и с большим и рандомным шагом.. Как тут можно реализовать?

вот что у сервера:
Код:
void Dialog::on_dataRead()
{
    struct
    {
        int CMD;
        int X;
        int Y;
        int Z;
        int Power;
    } sendingStruct;
   
    QByteArray readingData;
    while(serverSocket->bytesAvailable() > 0)
        readingData.append(serverSocket->readAll());
    memcpy(&sendingStruct, readingData.data() +1, sizeof(sendingStruct));
    QTextCursor curs = ui->textEdit->textCursor();
    curs.movePosition(QTextCursor::End);
    QString text = QString("CMD= %1\r\nX= %2\r\nY= %3\r\nZ= %4\r\nPower= %5").arg(sendingStruct.CMD).
                   arg(sendingStruct.X).arg(sendingStruct.Y).arg(sendingStruct.Z).arg(sendingStruct.Power);
    curs.insertText(text);
}
с QDataStream из примеров поставки не понял как длину пакета определять.

вот что идет с клиента:

Код:
void CServerConnection::SendData(QMap<QString, int> data)
{
    if (!connection->isOpen())
        return;

    struct
    {
        int CMD;
        int X;
        int Y;
        int Z;
        int Power;
    } sendingStruct;
    for (int i = 0; i < 100; i++)
    {
        sendingStruct.CMD = 33;
        sendingStruct.X = i;
        sendingStruct.Y = i+1;
        sendingStruct.Z = i*2;
        sendingStruct.Power = i*i;
        sendData.clear();
        char *buf = new char[sizeof(sendingStruct)];
        memcpy(buf, &sendingStruct,sizeof(sendingStruct));
        sendData.append(STX); // начало пакета
        sendData.append(buf, sizeof(sendingStruct));
        sendData.append(ETX); // конец пакета
        connection->write(sendData);
        connection->waitForBytesWritten();
        delete[] buf;
    }
}
Записан
Amigo_sa
Гость
« Ответ #3 : Декабрь 09, 2010, 11:49 »

В корне неправильно использовать memcpy для того чтобы записать структуру в бинарный буфер. Потому что мы в общем случае не знаем, как именно структура в памяти располагается. Надо написать функцию для упаковки структуры в поток и восстановления. Как вариант переопределить метод >> у BinaryStream
Записан
RedDog
Гость
« Ответ #4 : Декабрь 09, 2010, 11:54 »

В корне неправильно использовать memcpy для того чтобы записать структуру в бинарный буфер. Потому что мы в общем случае не знаем, как именно структура в памяти располагается. Надо написать функцию для упаковки структуры в поток и восстановления. Как вариант переопределить метод >> у BinaryStream
ну я всегда полагал, что она располагается линейно в памяти, в конце концов столько было примеров по поводу записи структуры в файл и ее восстановления оттуда, и ни у кого вроде с восстановлением проблем не возникало (если структура не содержит в себе указателей).
Но это все лирика, вопрос в другом: куда деваются пакеты и как их достать все из сети?
Записан
BRE
Гость
« Ответ #5 : Декабрь 09, 2010, 12:05 »

Но это все лирика, вопрос в другом: куда деваются пакеты и как их достать все из сети?
Они не куда не деваются, ты их вычитываешь с помощью readAll к себе в буфер, только обрабатывашь только первую структуру из всего пакета.

Так ты ничего работающего не напишешь, поверь. Нужны минимальные базовые знания.  Подмигивающий
Записан
RedDog
Гость
« Ответ #6 : Декабрь 09, 2010, 12:20 »

Нужны минимальные базовые знания.  Подмигивающий
 
просьба развернуть ответ! Подмигивающий
сделал через QTcpSocket::read

Код:
    char *buf = new char [sizeof(sendingStruct) + 2];
    while(serverSocket->bytesAvailable() > 0)
    {
        serverSocket->read(buf, sizeof(sendingStruct) + 2);
        memcpy(&sendingStruct, buf +1, sizeof(sendingStruct));
     ........
    }
остается вопрос, в случае если длина пакета меньше sizeof(sendingStruct) + 2 как тогда быть?
Записан
BRE
Гость
« Ответ #7 : Декабрь 09, 2010, 12:25 »

А ты посмотри в примерах Qt как сделано там.  Подмигивающий
Записан
RedDog
Гость
« Ответ #8 : Декабрь 09, 2010, 13:59 »

А ты посмотри в примерах Qt как сделано там.  Подмигивающий
Всё поговорками говорил.(с) к/ф Брат.
Ты имеешь ввиду пример Fortune Client/Server
и будет правильней через QDataStream делать?
Записан
BRE
Гость
« Ответ #9 : Декабрь 09, 2010, 15:36 »

Ты имеешь ввиду пример Fortune Client/Server
Да.

и будет правильней через QDataStream делать?
Да.
Что бы понять почему, стоит вспомнить о порядке следования байт на разных архитектурах, о сетевом порядке байт. QDataStream о этом знает и будет все делать как надо.
Записан
RedDog
Гость
« Ответ #10 : Декабрь 09, 2010, 16:04 »

Что бы понять почему, стоит вспомнить о порядке следования байт на разных архитектурах, о сетевом порядке байт. QDataStream о этом знает и будет все делать как надо.
в документации Qt такого нету, или не нашел.
а если сервера писать не на Qt, то как там определять последовательность байт?
Записан
BRE
Гость
« Ответ #11 : Декабрь 09, 2010, 16:13 »

а если сервера писать не на Qt, то как там определять последовательность байт?
http://ru.wikipedia.org/wiki/Порядок_байтов

Там есть отдельная часть про сетевой порядок.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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