2014-01-12 3 views
0

Я пытаюсь написать небольшую клиент-серверную программу. Клиент должен обнаруживать все серверы, работающие в одной локальной сети. Я попытался реализовать UDP-Broadcast с qt, но моя функция чтения возвращает -1 все время. Если я вызываю функцию dataAvailable() в сокете, она говорит, что читать 4 байта, но по какой-то причине они не читают их.Ошибка чтения UDP UDP

Сейчас я пытаюсь получить передачу на одной и той же машине и в одной и той же программы

Вот мой главный:

#include <iostream> 
#include <QString> 
#include <QThread> 

#include "../include/network.h" 

using namespace std; 
using namespace network; 

int main() { 
    Network *n = new Network(); 
    n->broadcast("test"); 

    if (n->dataAvailable()) { 
     cout << "Data available: "; 
     cout << n->getData().toStdString() << std::endl; 
    } else { 
     cout << "No data" << endl; 
    } 
    delete n; 
} 

и моя сеть класса:

#ifndef NETWORK 
#define NETWORK 

#include <QObject> 
#include <QUdpSocket> 
#include <iostream> 

namespace network { 

    class Network : public QObject { 
     Q_OBJECT 
    public: 
     const static int BROADCAST_PORT = 52433; 

     explicit Network(QObject *parent = 0) { 
      socket = new QUdpSocket(); 
      socket->bind (QHostAddress::Any, BROADCAST_PORT); 
     } 

     ~Network() { 
      delete socket; 
     } 

     bool dataAvailable() { 
      return socket->hasPendingDatagrams(); 
     } 

     QString getData() { 
      if (!dataAvailable()) { 
       return ""; 
      } 
      char *data = 0; 
      std::cout << socket->pendingDatagramSize() << std::endl; 
      std::cout << QString("recv: %1") 
        .arg(socket->readDatagram(data, 
           socket->pendingDatagramSize())).toStdString(); 
      return QString(data); 
     } 

     void broadcast(QString data) { 
      QUdpSocket *broadcast = new QUdpSocket(); 
      broadcast->connectToHost(QHostAddress::Broadcast, BROADCAST_PORT); 
      std::cout << broadcast->write(data.toStdString().c_str()) 
         << std::endl << std::endl; 
      delete broadcast; 
     } 

    private: 
     QUdpSocket *socket; 
    }; 

} 

#endif // NETWORK 

Результат:

4 

Data available: 4 
recv -1 

Что означает

  1. 4 байта отправляется с трансляцией
  2. сокет обнаруживает, что 4 байта доступен
  3. попытки прочитать 4 байта не удается
  4. QString возвращаемого getData() пуст

К сожалению, я не нашел никакой возможности получить более подробную информацию об ошибке

+1

Я не знаю, как работает Qt, но обычно, когда системный вызов, как [ 'recvfrom (2)'] (http://linux.die.net/man/2/recvfrom) выходит из строя, его возвращает '-1' и устанавливает код ошибки в глобальную переменную' errno'. Если вы проверили значение 'errno', вы, вероятно, увидите, что' errno' был 'EFAULT', указывая, что вы передали недействительный адрес ядру, предполагая, что' errno' не получает сброс Qt. –

+0

К сожалению, я не знал о 'errno' :(вы можете рекомендовать хорошее чтение? – Qw3ry

ответ

3

Вам определенно необходимо выделить память для чтения дейтаграммы. Теперь вы пытаетесь записать его в нулевой указатель.

// char *data = 0; 
std::cout << socket->pendingDatagramSize() << std::endl; 
QVector<char> buffer(socket->pendingDatagramSize()); // create buffer 
std::cout << QString("recv: %1") 
     .arg(socket->readDatagram(buffer.data(), 
       socket->pendingDatagramSize())).toStdString(); 
+0

Спасибо, это решило проблему. Я думал, что функция выделяет нужную ему память сама по себе, а указатель char * установлен на адрес, который находится в памяти. Но этот способ тоже имеет смысл. – Qw3ry

Смежные вопросы