C:通过 UDP 发送浮点数导致随机符号

C: Sending float over UDP results in random symbols

我的代码有问题,应该通过 udp 发送浮点数。如果我检查我的端口传入,我只会收到随机符号而不是我想要的数字。

printf("Lets send some cool data \n");
int clientSocket;

struct sockaddr_in serverAddress;
socklen_t addressSize;

unsigned char   l_remoteHostAddr_rg4ui8[4]  = {192,168,22,160};
unsigned short  l_remoteHostPort_ui16       = 5000;
int             l_udpSocket_i32;
unsigned int    l_sendState_bl;

// open udp connection
l_udpSocket_i32 = g_halMatlab_initConnection_i32( l_remoteHostAddr_rg4ui8, l_remoteHostPort_ui16 );

halImu_orientationValues l_imuMeasurements_st;
g_halImu_initImuSensors_bl();

/*Create UDP socket*/
clientSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

serverAddress.sin_family = PF_INET;
serverAddress.sin_port = htons(REMOTE_PORT);
serverAddress.sin_addr.s_addr = inet_addr(REMOTE_ADDR);

memset(serverAddress.sin_zero, '[=10=]', sizeof(serverAddress.sin_zero));

/*Initialize size variable to be used later on*/
addressSize = sizeof(serverAddress);

printf("Start Sending Messages\n");

int i = kbhit();
while(i != 'q')
    {
        sleep(1);
        g_halImu_triggerImuReading_bl();
        g_halImu_triggerBaroReading_bl();
        g_halImu_triggerGyroReading_bl();
        g_halImu_triggerAccReading_bl();

        l_imuMeasurements_st=g_halImu_getImuValues_str();

        l_sendState_bl = g_halMatlab_sendImuState_bl(l_udpSocket_i32, l_imuMeasurements_st);

        printf("Acc X %f \n", l_imuMeasurements_st.acc.x_f64);

        float k = l_imuMeasurements_st.acc.x_f64;

        char imu_x[16];

        sprintf(imu_x,"%f \n",k);
        printf(imu_x,'\n'); //this prints the right number 

        sendto(clientSocket, imu_x, (int)sizeof(imu_x), 0,
               (struct sockaddr *)&serverAddress,addressSize);
        printf("And send again....\n");
    }

如果我知道使用 nc -ul 5000,我会收到包含随机内容的 16 位字符串。

如果有人知道我的问题出在哪里,我会很高兴收到你的来信

祝你有愉快的一天!

imu_x是16个字符长,但是当你用sprintf()把一个float放进去,它就只有7个字符了。 space、换行符和尾随的空值再添加 3 个字符,但字符串中剩余的 6 个字符将未初始化,这可能是您在接收端看到的垃圾。

我建议您发送 strlen(imu_x) 字节,而不是发送 sizeof(imu_x) 字节。

除了不完全定义发送的缓冲区()之外,将float打印到这么小的缓冲区中很容易溢出。

float k = l_imuMeasurements_st.acc.x_f64;
char imu_x[16];
sprintf(imu_x,"%f \n",k);

如果 k 的值为 1.2345,则 imu_x[] 将变为 "1.234500 \n" - 至少需要 11 char。如果 k 的值类似于 -12345,那么结果将是 "-12345.000000 \n" 并且需要 16 char。很容易看出稍大的值将如何溢出缓冲区。一旦发生这种情况,其余代码就是 未定义的行为


相反,建议在打印时清除缓冲区并使用 %e,以便为 float 的整个范围提供重要数据。指定小数点后 13 位和 5 位的宽度。通过使用 snprintf(),缓冲区将不会被溢出。通过使用宽度 13(space、\n 和 \0 为 +3),缓冲区将始终打印到前 16 个 char.

memset(imu_x, 0 , sizeof imu_x);
// sign dig . digs e sign expo space \n [=11=]
//  1    1  1  5   1  1     3    1    1  1
snprintf(imu_x, sizeof imu_x, "%13.5e \n",k);

第一个问题是您发送了两次相同的数据。首先通过一个名为 clientSocket 的套接字,另一个通过另一个名为 l_udpSocket_i32 的套接字。我正在清理代码,以便只编译 clientSocket。

你的第二个问题是你试图打印imu_x的所有16个数据。您应该只打印书面字符。我添加了一个名为 written 的新变量。 运行 这样你就不会看到任何垃圾了。

printf("Lets send some cool data \n");
int clientSocket;

struct sockaddr_in serverAddress;
socklen_t addressSize;
int written;
char imu_x[16];

halImu_orientationValues l_imuMeasurements_st;
g_halImu_initImuSensors_bl();

/*Create UDP socket*/
clientSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

serverAddress.sin_family = PF_INET;
serverAddress.sin_port = htons(REMOTE_PORT);
serverAddress.sin_addr.s_addr = inet_addr(REMOTE_ADDR);

memset(serverAddress.sin_zero, '[=10=]', sizeof(serverAddress.sin_zero));

/*Initialize size variable to be used later on*/
addressSize = sizeof(serverAddress);

printf("Start Sending Messages\n");

int i = kbhit();
while(i != 'q')
    {
        sleep(1);
        g_halImu_triggerImuReading_bl();
        g_halImu_triggerBaroReading_bl();
        g_halImu_triggerGyroReading_bl();
        g_halImu_triggerAccReading_bl();

        l_imuMeasurements_st=g_halImu_getImuValues_str();

        printf("Acc X %f \n", l_imuMeasurements_st.acc.x_f64);

        float k = l_imuMeasurements_st.acc.x_f64;


        written = sprintf(imu_x,"%f \n",k);
        printf(imu_x,'\n'); //this prints the right number 

        sendto(clientSocket, imu_x, written, 0,
               (struct sockaddr *)&serverAddress,addressSize);
        printf("And send again....\n");
    }