Поэтому я знаю, что многие из вас будут советовать против этого, но я хочу отправлять поплавки через 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);
}
Это не вопрос TCP против UDP.
Во-первых, чтобы отправить одно значение с плавающей точкой, вы не интерпретируете его как адрес, а берете адрес с плавающей точкой
iResult = send(ConnectSocket, &f, (int) sizeof(f), 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 проще, потому что вам не нужно проверять соединение и успешность отправленных данных. Вы просто отправляете его без подключения к серверу.
Это неверно Как следует из названия, strlen
для строк. Вам нужно передать фактический размер буфера send
,