QT界面如何与局域网中的设备进行一对一数据交互?

火花20180731 2014-09-06 01:57:59
我用QT编写了一个用户界面,用来操作局域网中的设备(网络摄像头之类),
我通过QUdpSocket组播的方式把我的Mac地址打包成Xml数据报,然后发送出去,
设备通过嵌入式编程接收并解析我发的数据报,
然后设备将自己的Mac打包成Xml回执报文,发送到解析得出的Mac地址上(也就是我的网卡上),
然后我获取到数据解析得到他的Mac地址
我为设备分配一个IP然后将设置结果以单播形式发送到他的网卡上

目前的问题是,我的数据组播出去,且他已经成功解析并向我发送了回执
但是我却接收不到他的报文,自然也就无法解析
我的代码如下:
socketxml.h文件
--------------------------------
#ifndef SOCKETXML_H
#define SOCKETXML_H

#include <QThread>
#include <QString>
#include <QtNetwork>
#include <QTimer>
#include <QByteArray>
#include "global.h"

class SocketXml : public QThread
{
Q_OBJECT
public:
SocketXml();
~SocketXml();
public slots:
void SendXmlBuf(QString str); //发送Xml数据
void RecvXmlBuf(); //接收Xml数据
protected:
void run(); //处理收发操作线程
private:
QUdpSocket *udpsocket;
};

#endif // SOCKETXML_H
************************************************************************************************************
socketxml.cpp
----------------------------------------
#include "socketxml.h"
#include <QDebug>

SocketXml::SocketXml()
{
udpsocket= new QUdpSocket(this);
//udpsocket->bind(QHostAddress::AnyIPv4,Global::Instance().port,QUdpSocket::ReuseAddressHint);
udpsocket->bind(Global::Instance().port,QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
udpsocket->setSocketOption(QAbstractSocket::MulticastLoopbackOption,1);
udpsocket->setSocketOption(QAbstractSocket::MulticastTtlOption,255);
udpsocket->joinMulticastGroup(QHostAddress(Global::Instance().Mucst_ip));
}
SocketXml::~SocketXml()
{
quit();
wait();
delete udpsocket;
}

/*!
* \brief SocketXml::SendXmlBuf
* \param str
* 发送数据
*/
void SocketXml::SendXmlBuf(QString str)
{
int len=udpsocket->writeDatagram( //调用QUdpSocket成员函数writeDatagram()发送数据
str.toLatin1().data(), //将数据转换成字符串(char*)格式
str.length(), //发送字符串长度
//QHostAddress(Global::Instance().Mucst_ip), //发送数据到组播IP
QHostAddress::Broadcast, //发送到组内所有主机
Global::Instance().port); //发送端口
if(len!=-1)
{
qDebug()<<"writeDatagram已发送"<<len<<"字节数据";
}
else
{
qDebug()<<"发送失败";
}
}

/*!
* \brief SocketXml::RecvXmlBuf
* 接收数据
*/
void SocketXml::RecvXmlBuf()
{
qDebug()<<"正在检测...";
while(udpsocket->hasPendingDatagrams())
{
qDebug()<<"hasPendingDatagrams检测到数据包";
QByteArray byte;
QHostAddress getaddr;
quint16 getport;
byte.resize(udpsocket->pendingDatagramSize());
int strsize=udpsocket->readDatagram(
byte.data(), //数据内容
byte.size(), //数据大小
&getaddr, //发送者地址
&getport); //发送者端口
qDebug()<<"readDatagram读入"<<strsize<<"字节数据";
Global::Instance().RecvBuf.append(byte);
qDebug()<<"发送者地址:"<<getaddr<<"发送者端口:"<<getport;
}
}

/*!
* \brief SocketXml::run
* 重写QThread虚函数run(),用于添加线程工作
*/
void SocketXml::run()
{
if(Global::Instance().flag)
{
while(!Global::Instance().SendBuf.isEmpty())
{
SendXmlBuf(Global::Instance().SendBuf.dequeue()); //每次发送队首,发送完删除当前队首
}
RecvXmlBuf(); //发完数据进入接收状态
Global::Instance().flag=false; //接收完数据停止工作
}
exec();
}
...全文
1461 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
yaoyg81 2016-09-26
  • 打赏
  • 举报
回复
没下文了吗 也在找这方面资料
火花20180731 2014-09-10
  • 打赏
  • 举报
回复
引用 4 楼 u012586257 的回复:
蛮高深的样子,帮个人场吧
thank you!
mangoalx 2014-09-09
  • 打赏
  • 举报
回复
蛮高深的样子,帮个人场吧
火花20180731 2014-09-09
  • 打赏
  • 举报
回复
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
火花20180731 2014-09-06
  • 打赏
  • 举报
回复
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
火花20180731 2014-09-06
  • 打赏
  • 举报
回复
PC端的QT界面与局域网中的设备进行一对一通信 设备当然是没有IP的,自然不能像聊天室那样直接一个QUdpSocket就搞定了, 所以他向我发数据只能在数据链路层直接向我的网卡发数据,不经过IP, 而我的问题是------------他直接往我网卡发数据我该怎么接收数据, 是通过到数据链路层抓包过滤找到他发给我的数据包, 还是直接在上层进行什么样的操作把网卡自动处理好的数据拿到, 我向他发数据可以通过组播的方式发出去,但是可能网络中不止他一台设备 那我有时候要跟他进行一对一通信,我只向他一台设备发数据, 而他又没有IP所以我只能把数据往他的网卡中发送,他再从网卡里抓包 听说从网卡中收发数据要用到原始套接字 但是有两个问题,原始套接字是基于Linux系统内核的 首先必须有超级用户权限才能使用原始套接字 QT Creator无法获得超级用户权限 其二我的这款软件是要实现跨平台运行的 比如我现在是在Windows下做开发 这样一来Linux的头文件就识别不了 如果我要用winpcap库进行Windows下的底层通信就必须配置Winpcap环境 这样一来就无法在Linux系统下使用 以后说不定还会在安卓平台IOS平台使用 况且用户也不可能再在用软件之前还要开超级权限,还要配置环境 所以我想了解一下,QT库中有没有能实现这种底层通信的类 或者我和设备之间是否需要这样底层的通信

2,426

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 其他硬件开发
社区管理员
  • 其他硬件开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧