chbchen007 2023-03-27 11:33 采纳率: 100%
浏览 39
已结题

通过UDP采集数据,代码有问题,请教大家

通过UDP采集数据,代码有问题,请教大家
 通过UDP协议进行数据采集,首先通过本地机器(电脑)发送采集指令,
 之后每秒钟进行设备发送数据包的接受和处理。 
设备的数据采集厂家是这样要求的:
         设备: IP = 192.168.1.252, 端口号:1031
         电脑: IP = 192.168.1.101,端口号:1032

使用网络调试助手,按照下图设置是可以正常采集到数据的。

img

自己的代码如下,但接受不到数据。

BOOL CDeviceInterfaceMAXA02::StartMeasureUDP()
{
    SOCKET m_Local;
    SOCKADDR_IN m_LocalAddress;   //本地地址
    SOCKADDR_IN m_RemoteAddress; //远程地址
    int m_LocalAddressLen = sizeof(SOCKADDR);
    int m_RemoteAddressLen = sizeof(SOCKADDR);


    // socket环境
    WSADATA  wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return false;

    // socket对象
    m_Local = socket(AF_INET, SOCK_DGRAM, 0);
    if (m_Local == INVALID_SOCKET)
    {
        closesocket(m_Local);
        m_Local = INVALID_SOCKET;
        return false;
    }
    unsigned long on = 1;  //此值为0,会将套接字设置为阻塞(默认的);为1设置为非阻塞
    if (0 != ioctlsocket(m_Local, FIONBIO, &on))
    {
        AfxMessageBox("设置为非阻塞失败.");
    }

    // 绑定占用<ip, port>
    const char* ip = "192.168.1.101";
    short port = 1032;
    m_LocalAddress.sin_family = AF_INET;
    m_LocalAddress.sin_addr.S_un.S_addr = inet_addr(ip);
    m_LocalAddress.sin_port = 1032;
    
    auto ret = bind(m_Local, (sockaddr*)&m_LocalAddress, sizeof(m_LocalAddress));
    if (ret == SOCKET_ERROR)
    {
        closesocket(m_Local);
        m_Local = INVALID_SOCKET;
        return false;
    }
    listen(m_Local, 10);
    // 接收和发送
    
    m_RemoteAddress.sin_family = AF_INET;
    m_RemoteAddress.sin_port = 1031;
    m_RemoteAddress.sin_addr.S_un.S_addr = inet_addr("192.168.1.252");
    m_RemoteAddressLen = sizeof(m_RemoteAddress);

    int bytes_sent;
    bytes_sent = sendto(m_Local, (char*)xaCS, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaRU, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaMC, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaGS, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaST1, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaST2, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaHV, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    bytes_sent = sendto(m_Local, (char*)xaCB, 6, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
    
    std::vector<char> ucBuffer;
    ucBuffer.resize(24600);

    while (1)
    {
        int recvLen = recvfrom(m_Local, ucBuffer.data(), 24600, 0, (sockaddr*)&m_LocalAddress, &m_LocalAddressLen);
    }

    closesocket(m_Local);
    WSACleanup();
    
    return true;
}
运行结果及详细报错内容
 目前的问题是recvfrom返回的数据长度为-1
希望达到的效果
 希望像“网络调试助手”一样,1:“打开”本地机器(电脑)的IP地址和端口,2:实现电脑发送指令和接受数据。
  • 写回答

4条回答 默认 最新

  • Bony- 2023-03-27 12:55
    关注

    根据您提供的代码,问题可能出现在两个地方:接收数据的地址和端口号设置不正确,以及接收缓冲区的大小设置不足。

    首先,关于接收地址和端口号的设置。您在发送数据时指定了远程地址和端口号(192.168.1.252和1031),但在接收数据时,却将本地地址和端口号(192.168.1.101和1032)作为参数传递给了recvfrom函数。这可能会导致recvfrom无法正确接收到数据包。因此,您需要将接收地址和端口号设置为设备的IP地址和端口号,即:

    m_LocalAddress.sin_family = AF_INET;
    m_LocalAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    m_LocalAddress.sin_port = htons(1031);
    
    // ...
    int recvLen = recvfrom(m_Local, ucBuffer.data(), 24600, 0, (sockaddr*)&m_RemoteAddress, &m_RemoteAddressLen);
    

    另外,由于接收数据的缓冲区大小为24600,这可能不足以容纳一些大型数据包。如果数据包的大小超过了缓冲区的大小,那么接收操作可能会失败。建议将接收缓冲区的大小设置得更大一些,以确保能够接收到所有的数据包。您可以根据实际情况调整缓冲区的大小。
    最后,建议在代码中添加一些错误处理的代码,以便在出现问题时能够及时发现和解决问题。例如,可以在发送和接收操作之后检查返回值,如果出现错误,则输出错误信息并退出程序。
    希望这些提示能够帮助你解决问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月4日
  • 已采纳回答 3月27日
  • 创建了问题 3月27日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改