You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Winsock监听ADS-B数据端口47806无响应问题求助

问题分析与修复方案

首先,你的代码存在几个关键问题,导致它无法按预期响应ADS-B软件的报文。咱们一步步拆解:

核心问题点

  • 仅建立连接,未读取实际报文:accept()只是完成TCP握手建立连接,但ADS-B软件是在连接建立后才发送十六进制报文的。你的代码在连接建立后只输出"OK",却没有尝试接收数据,也没有维持连接来监听后续报文。
  • 缺少关键步骤的错误检查:socket创建、端口绑定、启动监听这些核心操作都没做返回值校验,可能在初始化阶段就已经失败了,你却完全没感知到。
  • 控制台输出未即时刷新:std::cout << "OK"的内容可能被控制台缓冲区缓存,没有立即显示出来,导致你误以为代码没触发。
  • 未正确管理客户端连接生命周期:accept得到的客户端socket没有关闭,也没有进入接收循环,无法持续获取ADS-B的报文数据。

修正后的代码示例

#include <winsock2.h>
#include <iostream>
#include <string>

#pragma comment(lib, "ws2_32.lib")

int main() {
    WSADATA WSAData;
    // 初始化Winsock并检查错误
    if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0) {
        std::cerr << "WSAStartup初始化失败: " << WSAGetLastError() << std::endl;
        return 1;
    }

    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        std::cerr << "Socket创建失败: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    SOCKADDR_IN socket_in{};
    socket_in.sin_addr.s_addr = htonl(INADDR_ANY);
    socket_in.sin_family = AF_INET;
    socket_in.sin_port = htons(47806);

    // 绑定端口并检查错误
    if (bind(sock, (SOCKADDR*)&socket_in, sizeof(socket_in)) == SOCKET_ERROR) {
        std::cerr << "端口绑定失败: " << WSAGetLastError() << std::endl;
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    // 启动监听并检查错误
    if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
        std::cerr << "监听启动失败: " << WSAGetLastError() << std::endl;
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    std::cout << "正在监听47806端口..." << std::endl;

    while (TRUE) {
        SOCKADDR_IN client_addr{};
        int client_addr_size = sizeof(client_addr);
        SOCKET client_sock = accept(sock, (SOCKADDR*)&client_addr, &client_addr_size);
        
        if (client_sock == INVALID_SOCKET) {
            std::cerr << "连接接收失败: " << WSAGetLastError() << std::endl;
            continue;
        }

        std::cout << "新连接建立!OK" << std::endl;

        // 启动接收循环,持续读取ADS-B报文
        char buffer[1024];
        while (TRUE) {
            int bytes_received = recv(client_sock, buffer, sizeof(buffer) - 1, 0);
            if (bytes_received <= 0) {
                // 连接关闭或出错
                std::cout << "连接已关闭或出现错误" << std::endl;
                closesocket(client_sock);
                break;
            }
            // 处理十六进制数据,这里先转成字符串输出
            buffer[bytes_received] = '\0';
            std::cout << "收到报文: " << buffer << std::endl;
        }
    }

    // 清理资源(实际因无限循环不会执行到)
    closesocket(sock);
    WSACleanup();
    return 0;
}

关键修复说明

  1. 添加完整错误检查:每一步Winsock调用都校验返回值,能快速定位初始化阶段的问题(比如端口被占用导致绑定失败)。
  2. 新增报文接收循环:accept成功后进入recv()循环,持续读取ADS-B软件发送的报文,直到连接关闭。
  3. 即时刷新控制台输出:用std::endl代替单纯字符串输出,自动刷新缓冲区,确保你能立即看到反馈。
  4. 正确管理socket资源:连接关闭或出错时及时关闭客户端socket,避免资源泄漏。

另外,如果你需要解析原始十六进制字节而非字符串,可以直接处理buffer中的字节数据,无需转成C风格字符串。

内容的提问来源于stack exchange,提问作者Pierre LAGOUTTE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:50:53