根据此页面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()只是简单的空; - ; ....
答案 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的定义而不是其他)