Почему я получаю странные результаты при чтении массива целых чисел из сокета TCP? - PullRequest
2 голосов
/ 23 марта 2009

Как было предложено в ответе на мой последний вопрос ( Как я могу отправить массив целых чисел через TCP в C? ), я пытался отправить массив длинных int, однако я могу делать что-то сломать решение ...

#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);

Преобразование в указатель при неправильной передаче?

При чтении на стороне клиента, вместо того, чтобы получать отправленные номера (1, 2, 3, 4), я получаю длинные номера, такие как 140088443806649 ...

#define ARRAY_LEN 4

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

Итак, предполагая, что мне нужно прочитать указатель, я попробовал это ...

#define ARRAY_LEN 4

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

Но это тоже не сработало (функция чтения вернула -1).

Ответы [ 3 ]

4 голосов
/ 23 марта 2009

Дополнительный указатель не нужен. Массив (который в основном является указателем) может быть передан напрямую. Вы неправильно используете размер указателя вместо размера типа данных (long); используйте sizeof (long) * ARRAY_LEN или просто sizeof (originalArray) вместо.

Запись:

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

Читать:

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

Если вы передаете массив в качестве указателя, то sizeof нельзя использовать для получения общего размера массива. В этом случае размер должен быть передан вместе с указателем, а размер должен быть составлен с помощью sizeof (long) * ARRAY_LEN.

Будьте осторожны при использовании типа, такого как долго, поскольку он не всегда имеет одинаковый размер на разных платформах (то есть 32-битный или 64-битный); предпочтение отдается типоразмерам типа int32_t . Также вы можете столкнуться с проблемами с endianess . Перед записью рассмотрите возможность замены значений на htonl .

2 голосов
/ 23 марта 2009

Я также хотел бы отметить, что в некоторых сценариях причиной возникновения проблем могут быть разные порядковые номера данных, хранящихся в памяти, и данных, передаваемых по сети, поэтому обязательно проверьте это, если работаете на низком уровне.

0 голосов
/ 23 марта 2009

Возможно, вы захотите взглянуть на код SmartNetwork в http://smartwinlib.org, если вы кодируете свой собственный TCPStream или что-то ...

Он содержит потоковые обертки для всех от TCP и вплоть до HTTP и даже SOAP, а код чрезвычайно небольшой, хотя и сильно шаблонизированный ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...