c ++ QT QUdp套接字不发送/接收数据?

时间:2016-10-23 07:19:06

标签: c++ qt sockets udp

根据此页面https://wiki.sa-mp.com/wiki/Query_Mechanism我可以向主机发送一些数据,它会向我回复一些信息,我是否正确? 如果没有,我会感激,如果有人可以帮助我。

然而,我正在做以下的代码,但它只是简单地做任何事O.O任何人都知道我做错了什么?

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QUdpSocket>
#include <qmessagebox.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QUdpSocket *mysock = new QUdpSocket(this);
    mysock->writeDatagram("i", QHostAddress("164.132.69.65"), 7777);
    QByteArray myarry;
    QHostAddress myhost;
    quint16 port;
    mysock->readDatagram(myarry.data(), myarry.size(), &myhost, &port);
    ui->textEdit->setText(myarry.data());
}

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

myarry.data()只是简单的空; - ; ....

1 个答案:

答案 0 :(得分:3)

QUdpSocket::readDatagram()(以及大多数Qt网络IO功能)在数据可用之前阻止阻止。这意味着如果您在尚未到达数据的位置调用它,则您在提供的缓冲区中没有任何数据,并且调用应返回-1

来自docs

  

只要数据报到达,就会发出readyRead()信号。在那里面   case,hasPendingDatagrams()返回true。致电pendingDatagramSize()   获取第一个待处理数据报的大小,readDatagram()   阅读它。

您应该从连接到readDatagram()信号的广告位中拨打readyRead()

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //mysock should be a member of the MainWindow class
    //so that you can access it from other functions
    mysock = new QUdpSocket(this);
    mysock->writeDatagram("i", QHostAddress("164.132.69.65"), 7777);
    connect(mysock, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams);
}

//add this slot to the class's declaration
void MainWindow::readPendingDatagrams(){
    //read datagrams in a loop to make sure that all received datagrams are processed
    //since readyRead() is emitted for a datagram only when all previous datagrams are read
    while(mysock->hasPendingDatagrams()){
        QByteArray datagram;
        datagram.resize(mysock->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        mysock->readDatagram(datagram.data(), datagram.size(),
                                &sender, &senderPort);

        //do whatever you want to received datagram
        ui->textEdit->setText(datagram.data());
    }
}

编辑:

看起来您发送到服务器的请求不符合your link中的规范。在您的代码中,您只是发送一封"i"字母而不是其他内容。

该页面表示(简而言之)您应该发送前缀"SAMP",然后是服务器的IP,然后是服务器的端口,之后您可以发送您的操作码(即{在你的情况下{1}}。

完全放弃,以下是我将如何实现它:

"i"

您需要解析的服务器二进制回复的格式在您链接的页面here中指定。

旁注:

我真的认为你应该在他们自己的类中分离构建请求和解析响应,而不是在MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //mysock should be a member of the MainWindow class //so that you can access it from other functions mysock = new QUdpSocket(this); QHostAddress serverAddress("164.132.69.65"); quint16 port= 7777; QByteArray data; //building request data+= "SAMP"; //"SAMP" prefix //convert to big endian to make sure the octets are sent in the specified order quint32 ipv4AddrBigEndian= qToBigEndian(serverAddress.toIPv4Address()); //convert to little endian to make sure port bytes are sent in the specified order quint16 portLittleEndian= qToLittleEndian(port); //add server ip address data.append(reinterpret_cast<char*>(&ipv4AddrBigEndian), sizeof(ipv4AddrBigEndian)); //add server port data.append(reinterpret_cast<char*>(&portLittleEndian), sizeof(portLittleEndian)); //add opcode data.append("i"); mysock->writeDatagram(data, serverAddress, port); connect(mysock, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams); } void MainWindow::readPendingDatagrams(){ //read datagrams in a loop to make sure that all received datagrams are processed //since readyRead() is emitted for a datagram only when all previous datagrams are read while(mysock->hasPendingDatagrams()){ QByteArray datagram; datagram.resize(mysock->pendingDatagramSize()); QHostAddress sender; quint16 senderPort; mysock->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); qDebug() << "received: " << datagram.toHex(); //do whatever you want to received datagram //you need to parse information you want from the datagram //It can NOT be just displayed as text in a QTextEdit (as it contains binary data) } } 类中使用所有这些(应该用于UI的定义而不是其他)