通过socket获取和解析udp的导航数据

在 C++ 中获取 UDP 数据,核心流程是:创建 Socket -> 绑定端口(Bind) -> 循环接收(Recvfrom) -> 按协议解析

由于导航数据通常是结构化的(如二进制或十六进制),建议直接映射到 struct

C++ 示例代码(Linux/Windows 通用逻辑)

这里以 Linux 环境为例,展示如何读取一个假设的导航数据包:

cpp 复制代码
#include <iostream>
#include <vector>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>

// 根据设备的通讯协议手册(报文格式)
// 1. 根据你的导航设备协议定义结构体 (注意对齐)
#pragma pack(push, 1) 
struct NavData {
    uint32_t header;    // 包头
    double lon;         // 经度
    double lat;         // 纬度
    float heading;      // 航向角
    // ... 其他字段
};
#pragma pack(pop)

int main() {
    int port = 8080; // 组合导航发送数据的目标端口
    int sockfd;
    char buffer[1024];

    // 2. 创建 UDP Socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Socket creation failed");
        return -1;
    }

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡
    servaddr.sin_port = htons(port);

    // 3. 绑定端口
    if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("Bind failed");
        return -1;
    }

    std::cout << "Waiting for Nav Data on port " << port << "..." << std::endl;

    while (true) {
        struct sockaddr_in cliaddr;
        socklen_t len = sizeof(cliaddr);
        
        // 4. 接收数据
        int n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&cliaddr, &len);
        
        if (n > 0) {
            // 5. 解析数据 (假设收到的就是 NavData 结构)
            if (n >= sizeof(NavData)) {
                NavData* data = reinterpret_cast<NavData*>(buffer);
                
                // 打印结果
                std::cout << "Lon: " << data->lon << " Lat: " << data->lat 
                          << " Heading: " << data->heading << std::endl;
            }
        }
    }

    close(sockfd);
    return 0;
}

关键点解析:

  1. #pragma pack(1) : 组合导航通常发送的是原始二进制流。这个指令防止 C++ 编译器在结构体中插入填充字节,确保内存布局与传感器发送的 协议文档 完全一致。
  2. INADDR_ANY : 如果你的电脑有多个网卡(比如网线连导航,WiFi上网),使用 INADDR_ANY 可以接收发往任何网卡的数据。
  3. 大端/小端 (Endianness) : 多数现代导航设备(及 X86 电脑)使用小端模式。如果数据乱码,请检查协议是否要求使用 ntohlntohs 进行字节序转换。
  4. 缓冲区大小 : buffer 应略大于设备发送的最长数据包。
相关推荐
晏宁科技YaningAI几秒前
VoIP系统的工程实现模型:从信令控制到媒体传输的完整架构解析
网络·人工智能·架构·系统架构·信息与通信
神奇霸王龙3 小时前
Claude Code屠榜:MiMo与Grok紧追Codex
服务器·网络·人工智能·gpt·ai·ai编程
TlSfoward4 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
数智化管理手记4 小时前
账龄分析手工统计易遗漏?自动账龄分析工具怎么搭建
大数据·网络·数据库·人工智能·数据挖掘
LabVIEW开发5 小时前
NI Package Manager安装LabVIEW时InternalServerError错误
网络·数据库·labview·labview知识·labview功能·labview程序
RD_daoyi5 小时前
外链权重暴跌至13%,品牌提及反超传统链接——2026年不做Digital PR,你的独立站等于隐形
运维·网络·学习·机器学习·搜索引擎
张小姐的猫6 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
国科安芯6 小时前
星间光链路:AS32S601型抗辐射MCU在空间激光通信终端控制中的技术实现
服务器·网络·单片机·嵌入式硬件·物联网·安全·信息与通信
可视化运维管理爱好者7 小时前
nVisual Studio:数据中心网络智能规划设计工具
网络·ide·visual studio
MetrixAeroCore7 小时前
光伏逆变器远程监控物联网卡流量极小但需常年在线的套餐推荐
网络