使用 UDP 协议和 writeDatagram 发送结构体

     2023-04-14     45

关键词:

【中文标题】使用 UDP 协议和 writeDatagram 发送结构体【英文标题】:Send a structure with UDP protocol and writeDatagram 【发布时间】:2014-08-01 03:49:25 【问题描述】:

我的目标是通过UDP协议发送一个结构,我的问题是我用来做它的函数与他参数中的结构不兼容。 (我正在使用 QT)

这是我制作的代码:

void MyUDP::sendUDP()

    typedef struct MyStructTag
    
       int test1;
       bool test2;
       char test3;
     MyStruct;

    MyStruct envoie;

    // Sends the datagram datagram
    // to the host address and at port.
    // qint64 QUdpSocket::writeDatagram(const QByteArray & datagram,
    //                      const QHostAddress & host, quint16 port)

    socket->writeDatagram(envoie, QHostAddress("10.100.14.79"), 4000);



我知道这一行是完全错误的:socket->writeDatagram(envoie, QHostAddress("10.100.14.79"), 4000); 但我不知道如何正确使用此功能,或者是否有替代此功能的方法?

感谢您的帮助。

【问题讨论】:

socket->writeDatagram( (const char*) &envoie, sizeof (envoie), QHostAddress("10.100.14.79"), 4000 ); 爱你...谢谢你的帮助,但是在函数的文档中我没有找到这个参数,这怎么可能? 该函数记录在 qt 文档qt-project.org/doc/qt-5/qudpsocket.html#writeDatagram 是的,我的IDE没有给我指定这个,感谢您的帮助,如果您愿意,可以为大家发布答案。 Ivan 的解决方案可能在这种情况下可以工作,因为结构在内存中是连续的,但如果您有任何动态分配的内容,则会失败。它也不允许转换为网络字节顺序(尽管 Qt 可能在内部处理了一些我不知道的事情,需要检查一下)。 【参考方案1】:

几乎总是通过网络发送裸结构是错误的,因为你不能保证它是如何打包的 - 成员之间是否有填充,字节序是什么,是否有任何额外的内部你不知道的领域?只有当接收器在同一平台上运行相同的二进制文件时,您才能这样做。鉴于fat binaries,仅运行相同的二进制文件是不够的。

正确的做法是使用QDataStream序列化结构:

void MyUDP::sendUDP()

  struct MyStruct
  
     int test1;
     bool test2;
     char test3;
  ;
  MyStruct envoie;

  QByteArray buf;
  QDataStream s(&buf, QIODevice::WriteOnly);
  // The encoding is big endian by default, on all systems. You 
  // can change it if you wish.
  if (false) s.setByteOrder(QDataStream::LittleEndian);
  s << (qint32)envoie.test1 << (quint8)envoie.test2 << (qint8)test3;
  socket->writeDatagram(buf, QHostAddress("10.100.14.79"), 4000);

我在another answer 中提供了有关同一主题的更多详细信息。

【讨论】:

你已经在其他话题上帮助我了,你真是太棒了。可以发送的 writeDatagram 是否有大小限制? @EvansBelloeil 这取决于使用的协议。因为在这种情况下,您正在发送 UDP,请参阅this question 了解详细信息。 TL;DR:只要 IPv4 流量没有被封装(比如在 *** 中),508 字节应该没问题。【参考方案2】:

在快速搜索socket-&gt;writeDatagram() 实际期望的内容 (see docs) 之后,似乎有两个具有此名称的重载函数。一个需要一个 const char* 和一个大小,另一个需要一个 QByteArray 引用。在这两种情况下,这意味着您需要将结构打包成这些格式,然后将它们解包到另一端的结构中。因此,在 const char* 的情况下,创建一个大小适合您的结构的字符数组

unsigned int size=sizeof(int)+sizeof(bool)+sizeof(char)
char cBuffer[size];

然后像这样打包

unsigned int nPos=0;
memcpy(cBuffer[nPos],envoie.test1,sizeof(int));
nPos+=sizeof(int);
memcpy(cBuffer[nPos],envoie.test2,sizeof(bool));
nPos+=sizeof(bool);
memcpy(cBuffer[nPos],envoie.test3,sizeof(char));

函数的第二种形式可能有更好的打包方式,但我对 Qt 不熟悉,所以你必须查看它以了解它是如何实现的,以及它是否比我上面给出的选项更好.使用我提供的选项,如果两台机器的字节序不同,您还需要注意字节序,它们可以切换解释字节的顺序。这对于整数类型最为重要。长度为一个字符的类型(即 char)不会成为问题,而且浮点数似乎通常也不是问题(尽管不要引用我的话)。 QtByteArray 使用起来可能会更好一些,但是快速浏览它上面的documentation 似乎并没有说明处理不同的字节序。处理不同字节序的一般方法是将事物转换为网络字节顺序或大字节序字节顺序。可能有一些函数可以将整数从本机字节序转换为网络字节顺序,然后在另一端转换回本机字节序。

【讨论】:

这个问题专门针对 Qt C++。您改为提供通用 C99 样式的答案。你的回答是“好的”,但这是一个不同的问题。在现代 C++ 中使用 memcpy 令人畏缩,而且几乎没有任何理由。 就我个人而言,我认为所有包含“我不熟悉 [x]”(其中“x”是问题上的标签)短语的答案都会适得其反,而且它们几乎普遍都是低的质量。

tcp协议和udp协议区别

...低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;文件传输程序udp协议:不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文(数据包),尽最... 查看详情

12.2-全栈java笔记:tcp协议和udp协议

 区别在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式就类似于发送短信,使用这种... 查看详情

tcp协议和udp协议

1.socket模块中的TCP协议a:格式:sk=socket.socket()b:参数:sk=socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)  查看详情

udp协议和黏包

udp是无链接的,先启动哪一端都不会报错模板importsocketudp_sk=socket.socket(type=socket.SOCK_DGRAM)#创建一个服务器的套接字udp_sk.bind((‘127.0.0.1‘,9000))#绑定服务器套接字msg,addr=udp_sk.recvfrom(1024)print(msg)udp_sk.sendto(b‘hi‘,addr)#对话(接 查看详情

tcp协议和udp协议的区别

一、TCP协议TCP(TransmissionControlProtocol)属于传输层协议,TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事... 查看详情

使用udp协议实现文字交互

...数据传输时,数据的发送端和接收端不建立逻辑连接。在使用UDP协议 查看详情

Skype 协议和超级节点

...何可靠?绝大多数互联网用户不是在NAT后面吗?如果我要使用这种技术创建一个P2P应用程序,如果没有没有防火墙的对等点会发生什么?我不明白你如 查看详情

网络编程的常识基于tcp协议的编程模型tcp协议和udp协议的比较基于udp协议的编程模型

1.网络编程的常识目前主流的网络通讯软件有:微信、QQ、YY、陌陌、探探、飞信、阿里旺旺、...在吗?1.1七层网络模型(熟悉)为了保证数据传递的可靠安全等等,ISO(国际标准委员会组织)将数据的传递从逻辑上划分为以下七层:... 查看详情

网络编程——tcp协议和通信(代码片段)

第1章 TCP通信TCP通信同UDP通信一样,都能实现两台计算机之间的通信,通信的两端都需要创建socket对象。区别在于,UDP中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地发送数据。而TCP通信是严格区... 查看详情

使用 Swift 协议和扩展覆盖对象方法

】使用Swift协议和扩展覆盖对象方法【英文标题】:OverrideobjectmethodusingSwiftprotocolsandextensions【发布时间】:2020-04-2818:24:43【问题描述】:我想重写一个在框架中声明并在扩展中实现的方法。这是我尝试过的:importUIKit//Codefromadepen... 查看详情

tcp/ip协议和网络安全

 传输层协议    TCP可靠传输 编号  丢包重传 流量控制  三层握手  建立会话    UDP 不可靠传输 不需要编号  不建立会话 广播 多播land攻击&nbs 查看详情

AppDelegate 中的 UIActivityView 使用协议和委托

】AppDelegate中的UIActivityView使用协议和委托【英文标题】:UIActivityViewinAppDelegateusingprotocolanddelegation【发布时间】:2014-01-0913:50:27【问题描述】:我正在尝试在我的应用中实现UIActivityView。它已经在工作了,但是我现在需要做的是... 查看详情

如何在 UINavigationController 中使用协议和委托

】如何在UINavigationController中使用协议和委托【英文标题】:HowtouseProtocolsandDelegateswithUINavigationController【发布时间】:2019-12-0500:59:18【问题描述】:我有一个Welcome控制器作为基础。它根据用户单击的按钮以模态方式呈现Login或Sign... 查看详情

http协议和fiddler

HTTP概念HTTP请求HTTP响应Fiddler概念HTTP(全称为“超文本传输协议”)是一种应用非常广泛的应用层协议.HTTP往往是基于传输层的TCP协议实现的.(HTTP1.0,HTTP1.1,HTTP2.0均为TCP,HTTP3基于UDP实现)HTTP请求请求的格式:首行:方法类型URL版本号... 查看详情

windowsserverfailovercluster使用的协议和端口

WindowsServerFailoverCluster使用的协议和端口WindowsServer群集服务,群集服务用于控制服务器群集操作和管理群集的内部平面文件数据库。一个群集是独立服务器组合起来并作为一个单独实体对外提供服务的集合。用户看到的群集是一... 查看详情

ftp协议和tcp协议,啥关系?如何理解socket?

...CP可以跑HTML,图像,超链SOCKET是将TCP,UDP协议的功能打包使用,一般给开发人员用的。参考技术A说简单一点:ftp把文件拆开了,分成包tcp把这些包往其它地方传然后靠ip把包分到目标然后再经过tcp到目标的ftp然后目标的ftp把文件... 查看详情

tcp与udp比较

tcp协议和udp协议的差别TCPUDP是否连接面向连接面向非连接传输可靠性可靠不可靠应用场合传输大量数据少量数据速度慢快1、TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。在网络层有IP协议、ICMP协议、ARP协议、RA... 查看详情

开源飞控初探:mavlink协议和java库

概述MAVLink协议是一种(应用层)数据协议,不依赖传输协议。传输层可以是TCP、UDP、RS232串口,甚至基于WebSocket。在定义数据的基础上,补充描述了几种子协议(microservice,直译是微服务)的现有... 查看详情