I have a very strange error.
I have two applications that communicate over TCP / IP.
Appendix A is the server, and Appendix B is the client.
Application A sends a bunch of float values to application B every 100 milliseconds.
The error is this: sometimes some of the float values received by application B do not match the values passed by application A.
Initially, I thought the problem was with the Ethernet or TCP / IP drivers (something like data corruption). Then I tested the code on other Windows machines, but the problem persists.
Then I tested the code on Linux (Ubuntu 10.04.1 LTS) and the problem is still there !!!
Values are recorded immediately before they are sent and immediately after they are received.
The code is pretty simple: the message protocol has a 4-byte header like this:
struct MESSAGE_HEADER {
unsigned short type;
unsigned short length;
};
struct ORIENTATION_MESSAGE : MESSAGE_HEADER
{
float azimuth;
float elevation;
float speed_az;
float speed_elev;
};
struct MESSAGE : MESSAGE_HEADER {
char buffer[512];
};
static int receive(SOCKET socket, void *buffer, size_t size) {
int r;
do {
r = recv(socket, (char *)buffer, size, 0);
if (r == 0 || r == SOCKET_ERROR) break;
buffer = (char *)buffer + r;
size -= r;
} while (size);
return r;
}
static int send(SOCKET socket, const void *buffer, size_t size) {
int r;
do {
r = send(socket, (const char *)buffer, size, 0);
if (r == 0 || r == SOCKET_ERROR) break;
buffer = (char *)buffer + r;
size -= r;
} while (size);
return r;
}
static bool receive(SOCKET socket, MESSAGE &msg) {
int r = receive(socket, &msg, sizeof(MESSAGE_HEADER));
if (r == SOCKET_ERROR || r == 0) return false;
if (ntohs(msg.length) == 0) return true;
r = receive(socket, msg.buffer, ntohs(msg.length));
if (r == SOCKET_ERROR || r == 0) return false;
return true;
}
static bool send(SOCKET socket, const MESSAGE &msg) {
int r = send(socket, &msg, ntohs(msg.length) + sizeof(MESSAGE_HEADER));
if (r == SOCKET_ERROR || r == 0) return false;
return true;
}
When I get the message "orientation", sometimes the value "azimuth" is different from the value specified by the server!
Shouldn't the data be the same all the time? Does TCP / IP guarantee data delivery without distortion? maybe an exception in the mathematical coprocessor affects the TCP / IP stack? The problem is that I get a small number of bytes first (4 bytes) and then the body of the message?
EDIT:
The problem is the endianess substitution procedure. The following code folds the continent of a specific float around, and then swaps it again and prints the bytes:
#include <iostream>
using namespace std;
float ntohf(float f)
{
float r;
unsigned char *s = (unsigned char *)&f;
unsigned char *d = (unsigned char *)&r;
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
return r;
}
int main() {
unsigned long l = 3206974079;
float f1 = (float &)l;
float f2 = ntohf(ntohf(f1));
unsigned char *c1 = (unsigned char *)&f1;
unsigned char *c2 = (unsigned char *)&f2;
printf("%02X %02X %02X %02X\n", c1[0], c1[1], c1[2], c1[3]);
printf("%02X %02X %02X %02X\n", c2[0], c2[1], c2[2], c2[3]);
getchar();
return 0;
}
Conclusion:
7F 8A 26 BF 7F CA 26 BF
those. assigning a float probably normalizes the value, creating a different value from the original.
Any input is welcome.
EDIT2:
. , , swapped float, return, CPU. , , swapped float, .