Отправить числовые данные через TCP / IP Ethernet

Поэтому я знаю, что многие из вас будут советовать против этого, но я хочу отправлять поплавки через TCP / IP на сервер TCP, работающий на SoC (Zynq7020, с сервером на Arm A9). Я хочу, чтобы это работало как простое доказательство концепции, прежде чем перейти к использованию UDP, который, вероятно, больше подходит для отправки необработанных данных. У меня проблемы с преобразованием float в массив символов на стороне клиента и обратно на сервер. Хотя я не уверен, что это лучший подход.

Я использую WinSocket API и отправляю данные так (хотя я не уверен, что это правильно или эффективно!):

char * sendbuf;
sendbuf = reinterpret_cast<char *>(f);
iResult = send(ConnectSocket, sendbuf, (int) strlen(sendbuf), 0);

В основном это правильно, и без использования UDP, что является лучшим способом плавать через TCP. Я полагаю, что декодирование, по сути, приведет к обратному проектированию метода, используемого для отправки числа с плавающей точкой как char *

—Ниже приведен полный рабочий пример отправки поплавков через WinSock на процессор Zynq ARM LwIP—

Хост Windows 7 (возможно, htonf, но я на x86, так что нет никаких проблем с порядком байтов):

int FPGA_Accelerator::sendFloat(float* f) {
char *sendbuf;
int iResult;
char arr[4];

*(float*)arr= *f;

printf("Sending "); printf(arr); printf("\n");
iResult = send(connection, arr, (int) sizeof(arr), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(connection);
WSACleanup();
return -1;
}

printf("Bytes Sent: %ld\n", iResult);

return 1;
};

Код Zynq. Где в recv_callback я вызываю функцию parse_input(p->payload)

void parse_input(char* input){
xil_printf("Input : ");
xil_printf(input);
xil_printf("\n\r");

u32 d = *(u32*)input;
union v{
float f;
u32 u;
};
union v val;
val.u = d;

printf("Value u32 = %i \n\r",val.u);
printf("Value float = %f \n\r",val.f);

}

0

Решение

Это не вопрос TCP против UDP.

Во-первых, чтобы отправить одно значение с плавающей точкой, вы не интерпретируете его как адрес, а берете адрес с плавающей точкой

iResult = send(ConnectSocket, &f, (int) sizeof(f), 0);

Но это работает, только если у вас одинаковая архитектура на обоих концах связи.

Чтобы сделать его независимым от проблем архитектуры, вы должны использовать некоторые Представление внешних данных для передачи из одной системы в другую. Кроме того, вы также можете использовать текстовый протокол и преобразовать значение с плавающей точкой в ​​строку.

0

Другие решения

Неважно, что вы отправляете — это float или string. Вы отправляете данные в виде массива байтов и получаете их на другой стороне и интерпретируете их как хотите. Так что в вашем случае вы должны отправить число с плавающей запятой длиной 4 байта. Вы должны отправить 4 байта в виде массива байтов, а с другой стороны привести его к плавающей точке и использовать его.

iResult = send(ConnectSocket, (char*)&f, (int) sizeof(float), 0);

в приемной части:

char *receivebuf;
// read data from socket
float *receivedFloat = (float*)receivebuf;

Использовать UDP проще, потому что вам не нужно проверять соединение и успешность отправленных данных. Вы просто отправляете его без подключения к серверу.

1

Это неверно Как следует из названия, strlen для строк. Вам нужно передать фактический размер буфера send,

-1
По вопросам рекламы [email protected]