吃定彩虹391 2024-03-18 18:16 采纳率: 0%
浏览 455
已结题

UDP通信发送数据出现Destination unreachable问题

VS2019实现UDP通信时,上位机通过 sendto() 给下位机发送命令后下位机无变化。通过wireshark抓包发现数据已发出,但发出后紧接着出现ICMP错误消息Destination unreachable(Port unreachable)

img

#include <stdio.h>
#include <WinSock2.h>
#include <vector>
#include "iostream"
#include "fstream"
#include <sstream>
#include "string"
#include <iomanip>

using namespace std;

vector<int> data;

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

int main(void)
{
    WSADATA wsd;     // 初始化Socket的变量
    SOCKET s;        // 用于通信的Socket句柄
    SOCKADDR_IN sRecvAddr;    // 分别为接收地址和发送地址
    USHORT uPort = 12000;                // 通信端口
    int nResult = 0, nSenderAddrSize = sizeof(sRecvAddr);

    // 初始化Socket2.2版本
    nResult = WSAStartup(MAKEWORD(2, 2), &wsd);
    if (nResult != NO_ERROR)
    {
        printf("WSAStartup failed:%d\n", WSAGetLastError());
        system("pause");
        return 1;
    }

    // 创建一个Socket,与上位机bind,SOCK_DGRAM表示UDP类型
    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (s == INVALID_SOCKET)
    {
        printf("socket failed:%d\n", WSAGetLastError());
        system("pause");
        return 1;
    }


    // 填充上位机Socket接口
    memset(&sRecvAddr, 0, sizeof(sRecvAddr));
    sRecvAddr.sin_family = AF_INET;                                // 地址协议,AF_INET支持TCP和UDP
    sRecvAddr.sin_port = htons(uPort);                             // 通信端口,htons转为网络字节顺序
    sRecvAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.11");    // 上位机端口ip


    //发送数据
    CHAR buf[40] = { 0x0b, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x0c, 0x64, 0x00, 0xc8, 0x00, 0x2c, 0x01, 0x90, 0x01, 0x01, 0x00, 0x8f, 0x72, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf7, 0xf2, 0xfd, 0xe7};
    
    Sleep(500);

    nResult = sendto(s, buf, 40, 0, (SOCKADDR *)&sRecvAddr, nSenderAddrSize);
    if (nResult == SOCKET_ERROR)
    {
        printf("sendto failed:%d\n", WSAGetLastError());
        system("pause");
        return 1;
    }
    else
    {
        printf("sendto succed\n");
    }

    // 关闭Socket
    nResult = closesocket(s);
    if (nResult == SOCKET_ERROR)
    {
        printf("closesocket failed:%d\n", WSAGetLastError());
        system("pause");
        return 1;
    }
    // 清理Socket
    WSACleanup();

    system("pause");
    return 0;
}

运行代码显示“sendto succed”,但下位机接收到的数据无变化。

已排除是发送命令的问题,端口号和ip地址应该也没问题,使用网络调试助手发送同样的命令可以实现对应的功能。已尝试关闭防火墙,同样没有效果。

img

  • 写回答

25条回答 默认 最新

  • Watch the clown 2024-03-25 16:59
    关注
    获得0.60元问题酬金

    有看看数据包多大吗,可以朝着数据发送和接收的时机不同步方向排查排查

    评论

报告相同问题?

问题事件

  • 系统已结题 3月26日
  • 赞助了问题酬金15元 3月18日
  • 修改了问题 3月18日
  • 创建了问题 3月18日