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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: помогите с QUdpSocket  (Прочитано 4417 раз)
puh
Гость
« : Ноябрь 09, 2013, 09:48 »

Приветствую всех.
Накидал приложение на QT 5.1.0, которое общается по Езернету с внешним устройством (плата с ПЛИСкой) с использованием UDP. Код взял с примера.
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    addressClient.setAddress("201.1.1.1");
    udpSocket = new QUdpSocket(this);

    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(read()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initServer()
{
    bool ok = udpSocket->bind(1111);  // Привязка собственного IP-адреса к порту 1111
//    connect(udpSocket, SIGNAL(readyRead()),
//            this, SLOT(read()));
    if( ok )
    {
/*        QMessageBox::information(this, QObject::tr("Server"),
                                       QObject::tr("The server is running on port 1111."));
*/
        ui->label->setText("Init: Ok");
    }
    else
    {
/*        QMessageBox::critical(this, QObject::tr("Server"),
                                       QObject::tr("Error :: %1.\n")
                                       .arg(udpSocket->errorString()));
*/
        ui->label->setText("Init: No");
    }
}

void MainWindow::on_pushButton_clicked()
{
     initServer();
}

void MainWindow::on_pushButton_2_clicked()
{
    QByteArray data;
    QDataStream out(&data, QIODevice::WriteOnly);

    out << qint8(16) << qint8(38);

    udpSocket->writeDatagram(data, addressClient, 1111);

//    ui->label_2->setText("Error: " + QString::number(udpSocket->error()));
}

void MainWindow::read()
{
    QByteArray datagram;
    datagram.resize(udpSocket->pendingDatagramSize());
    QHostAddress *address = new QHostAddress();
    quint16 port = 0;
    qDebug() << "read";
//    do
//    {
        udpSocket->readDatagram(datagram.data(), datagram.size(), address, &port);
        qDebug() << "QHostAddress: " << address->toString() << " sourcePort: " << port;
        QDataStream in(&datagram, QIODevice::ReadOnly);
        qDebug() << "size DataGram: " << in.device()->size();

        qint8 a, b;
        in >> a;
        in >> b;
        qDebug() << a << " " << b;
//    }while(udpSocket->hasPendingDatagrams());
}
Данные в сети контролирую WireShark'ом.
Если нажать pushButton_2, то на плату приходит пакет, плата отвечает одной или двумя датаграммами, Qt-приложение принимает эти датаграммы, и все счастливы.
НО!! если плата сама инициирует передачу датаграммы в линию, отмечу САМА, а не в ответ на принятые данные, то Qt-приложение ни.. не реагирует.
Я уже пробовал с платы передавать в разные моменты, после небольшой паузы после двухстороннего обмена, до него, и нифига. Пакеты, отсылаемые с платы в обоих случаях, абсолютно одинаковые (даже идентификаторы пакетов и контр.суммы одинаковые).

Где что попинать, чтобы приложение принимало UDP-пакеты не после отправки своих данных.

З.Ы.: в Qt с сетями почти не работал.
З.З.Ы.: Когда-то делал два приложения клиент-сервер работающие на разных машинах - проблем не было. сервер и клиент принимали/отправляли данные.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Ноябрь 09, 2013, 16:09 »

Логи WireShark'а покажите на всякий случай - вдруг чего не увидели.
Подключение на прямую к компу или через какое-то сетевое оборудование?
Логи где снимаете WireShark'ом? На том же компьютере, что и программа работает?
Фаервол/брандмауэр имеются/включены?
Записан
puh
Гость
« Ответ #2 : Ноябрь 09, 2013, 16:55 »

Спасибо всем за участие.
Ответ оказался банальным - НЕВНИМАТЕЛЬНОСТЬ. Сто раз все смотрел-пересмотрел, а не увидел разницу в контрольных суммах пакетов, которые передаются из платы в разных ситуациях. В одном случае она равна 0х3c5b, а в другом - 0x3c5d, а я не заметил разницу. Видимо долго сидел и взгляд замылился.
Теперь сделал правильные контрольные суммы в обоих случаях и сервак принимает все пакеты.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Ноябрь 09, 2013, 17:03 »

Можно было и 0 просто поставить. В udp контрольная сумма не обязательна, ну хотя всё таки хоть какая-то проверка.
Записан
puh
Гость
« Ответ #4 : Ноябрь 09, 2013, 20:16 »

Да, можно, это я тоже пытался делать, но тогда у меня ничего не вышло, и я решил, что это не работает. Но сейчас я понял, что в то время, когда я ЭТО тестировал, мой проект просто был СЫРОЙ и не вполне работоспособный. Сегодня попробовал снова с НУЛЕВОЙ CRC_UDP и все сработало.
Довольно сложно одному отлаживать одновременно две совершенно разные системы: с одной стороны - плата с ПЛИСкой со своими тараканами, с другой приложение ПК, которое тоже не было отлажено.
Записан
tryx3j16
Гость
« Ответ #5 : Ноябрь 20, 2013, 19:53 »

Похожая проблема была и у меня......
Очень помогла информация отсюда. Спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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