我有一個客戶端,它在范圍內生成一個隨機浮點數[0..10]。此客戶端通過套接字將浮點值發送到服務器,服務器必須顯示它。我一直在試圖弄清楚如何通過套接字正確發送浮點數,但我無法到達任何地方。我設法直接發送了值,但我想要做的是將浮點數轉換為網路表示并回傳,所以我想使用這些函式htonl(),ntohl()但我一直沒有這樣做。我不想在這里復制整個服務器/客戶端代碼,因為它有點多,所以我對發生的事情進行了一個小的模擬,這會產生與服務器/客戶端代碼相同的問題。
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char* argv[]) {
uint32_t tmp, data;
srand(time(NULL));
float rand_float = ((float)rand() / (float)RAND_MAX) * 10;
printf("Generated random float = %f\n", rand_float);
// client converts to network representation(big endian) and sends the data
memcpy(&tmp, &rand_float, sizeof(tmp));
tmp = htonl(tmp);
// simulate sending the data over the network
memcpy(&data, &tmp, sizeof(data));
// server receives the data and has to convert it to host representation (little endian in my case)
float res = (float) ntohl(data);
printf("After send: %f\n", res);
return 0;
}
它與我在服務器/客戶端案例中想要的非常相似。如您所見,客戶端將隨機浮點資料復制到一個uint32_t變數中,將其轉換為網路表示并發送。服務器在data型別為 的變數中接收該資料uint32_t,將其轉換為主機表示,并將該值轉換為浮點數。我希望這能奏效。但是當我運行它時,我得到類似的東西:
Generated random float = 9.266754
After send: 1091847296.000000
或者類似的東西。顯然它不起作用。確切的行為發生在我的服務器/客戶端代碼中,我得到了類似的輸出。同樣,在服務器/客戶端代碼中,每當我從網路表示中洗掉該轉換并在我的機器上運行服務器和客戶端代碼時,一切都按預期作業,所以我很確定問題出在此轉換中的某個地方,但我不看不出上面的代碼有什么問題。我在這里閱讀了其他問題,詢問這種型別的轉換(這就是我發現這種發送浮點數的方法的地方),但它們沒有解決我的問題。
uj5u.com熱心網友回復:
float res = (float) ntohl(data);
您必須將這些位重新解釋為浮點數,而不僅僅是將整數轉換為浮點數。
你可以例如做:
float res = 0.0;
uint32_t tmp2 = ntohl(data);
memcpy(&res, &tmp2, sizeof(tmp2));
假設您生成 float 3.23。它具有二進制表示:01000000010011101011100001010010, 或1078900818。您執行位元組交換,發送它,然后再次交換位元組。現在你有了原始的表示,但你只是做了(float)1078900818,這只是“1078900818”。只是強制轉換是行不通的,因為浮點數是IEEE-754編碼的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/351271.html
