C:通过UDP发送浮点数会产生随机符号

时间:2016-06-09 00:49:48

标签: c udp

我的代码中有一个问题,应该在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, '\0', 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位字符串。

如果有人知道我的问题可能在哪里,我会很高兴收到你的回复

度过美好的一天!

3 个答案:

答案 0 :(得分:2)

imu_x长度为16个字符,但是当您使用sprintf()将浮点数放入其中时,它只会有7个字符。空格,换行符和尾随空值再添加3个字符,但字符串中剩余的6个字符将是未初始化的,这可能是您在接收端看到的垃圾。

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

答案 1 :(得分:2)

第一个问题是您要发送两次相同的数据。首先通过一个名为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, '\0', 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");
    }

答案 2 :(得分:1)

除了不完全定义发送的缓冲区(@Barmar)之外,将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(空格为+3,\ n和\ 0),缓冲区将始终打印到前16 char

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