tags:

views:

241

answers:

3

As was suggested in an answer to my last question (How do I send an array of integers over TCP in C?), I tried to send an array of long int, however I may be doing something to break the solution...

#define ARRAY_LEN 4

/* I'm using long because the numbers are very large,
 * but in this example they're small to save space. */
long originalArray[ARRAY_LEN] = { 1, 2, 3, 4 };

myObject.SetMyArray(originalArray);

// NOTE: The following is in a different function.

long *myArrayFromFunction = myObject.GetMyArray();

write(clientSocketFD, myArrayFromFunction, sizeof(myArrayFromFunction) * ARRAY_LEN);

Is converting to a pointer then passing incorrect?

When reading on the client side, instead of getting the numbers I sent (1, 2, 3, 4), I get long numbers such as 140088443806649...

#define ARRAY_LEN 4

long targetArray[ARRAY_LEN];
read(socketFD, targetArray, sizeof(targetArray) * ARRAY_LEN);

So, assuming that I need to read into a pointer, I tried this...

#define ARRAY_LEN 4

long *targetArray;
read(socketFD, targetArray, sizeof(targetArray) * ARRAY_LEN);

But this didn't work either (the read function returned -1).

+4  A: 

The extra pointer is unnecessary. The array (which basically is a pointer) can be passed directly. You are incorrectly using the size of the pointer instead of the size of the data type (long); use sizeof (long) * ARRAY_LEN or just sizeof (originalArray) instead.

Write:

#define ARRAY_LEN 4
long originalArray[ARRAY_LEN] = { 1, 2, 3, 4 };
write(clientSocketFD, originalArray, sizeof (originalArray));

Read:

#define ARRAY_LEN 4
long targetArray[ARRAY_LEN];
read(socketFD, targetArray, sizeof (targetArray));

If you are passing the array as a pointer, then sizeof cannot be used to get the total size of the array. In that case, the size must be passed along with the pointer and the size constructed with sizeof (long) * ARRAY_LEN.

Be careful using a type such as long since it is not always the same size on different platforms (i.e. 32-bit versus 64-bit); favor sized types like int32_t instead. Also, you can run into issues with endianess as well. Consider byte-swapping the values with htonl before writing.

Judge Maygarden
Yes, but what if the array comes from a function, as you know you can't return arrays from functions so I had to use a pointer. Are you saying that the pointer should be converted back to its original array form?
nbolton
@Nick: then you should use sizeof(long) * element_count as the size to send.
Evan Teran
+2  A: 

I would also like to point out that in some scenarios the different endianness for data stored in memory and data sent over network can be the reason of issues, so make sure that you check this out if you are working at low level.

Anonymous
That was certainly a problem in the past, but these days most software runs on Intel architecture. Certainly it's something to consider if you're sending data to a Unix server and you don't know if it's Intel, SPARC, Power or something different.
Paul Tomblin
Passing data between C and Java on x86 will also need the endianness reversed.
Mike Houston
"a problem in the past, but these days most software runs on Intel architecture." Are you serious? Wronge attitude to write good quality code IMHO.
ypnos
A: 

You might want to have a look at the SmartNetwork code in http://smartwinlib.org if you're coding your own TCPStream or something...

It contains stream wrappers for all from TCP and all the way up to HTTP and even SOAP and the code is extremely small, though heavily templated...

Thomas Hansen