2013-11-19 5 views
2

Я пытаюсь реализовать программу для отправки структуры через сокет C++ с клиента на сервер.Отправка структуры через сокет

Что я до сих пор работаю нормально на своем собственном компьютере (как на сервере, так и на клиенте на моем собственном компьютере), но я подозреваю, что у меня могут быть проблемы при запуске сервера и клиента на разных компьютерах.

То, что я до сих пор:

struct myStruct 
{ 
    int whatever; 
}; 

//Sender 

myStruct obj; 
obj.whatever = 123; 
char *byteStream = (char *) &obj; 

write(socketFD, byteStream, sizeof(myStruct)); 

//Receiver 

char *byteStream = new char[sizeof(myStruct)]; 
read(socketFD, byteStream, sizeof(myStruct)); 

myStruct *received = (myStruct *) byteStream; 
cout<<received->whatever; 

Оператор соиЬ на þér отпечатков приемника 123.

+2

Предупреждение: если вы используете сокеты TCP, то вызов 'read' может принимать * меньше *, чем то, что было отправлено, и вы должны прочитать в цикле, чтобы получить все. Не очень вероятно, с такой небольшой структурой, но все же о чем подумать. –

+1

Еще одно предупреждение: если вы отправляете структуру, содержащую указатели, эти указатели будут отправляться «как есть», но то, что они указывают, не будет отправлено. Таким образом, на принимающей стороне у вас есть отклоненные указатели в структуре. Кроме того, вы можете с легкостью отправлять указатели от одного процесса к другому на одном компьютере, на картах виртуальной памяти и все такое, поэтому еще меньше будет отправлять указатель на совершенно другой компьютер. –

+0

Данные не содержат указателей. Также я буду использовать UDP-сокет для этого назначения. –

ответ

4

Это должно работать на разных компьютерах, пока byte order одинакова (например, оба ПК).

+0

Действительно?Я начал думать, что char * byteStream = (char *) &obj; в основном присваивает адрес памяти obj байтуStream, и поскольку память распространена, приемник печатает правильное значение. –

+0

Нет, он интерпретирует указатель на obj как char *, чтобы этот указатель мог быть передан write(). – Reunanen

+0

Большое вам спасибо за помощь! Ожидается, что порядок байтов будет таким же. –

3

Различные системы могут использовать разные byte order и structure padding. Вы должны быть уверены, что ваши структуры: packed с обеих сторон. Обычно вы всегда отправляете многобайтные целые числа в сетевом порядке (big endian). Преобразуйте байтовые заказы с ntohl и друзьями.

+0

Ожидается, что порядок байтов будет таким же, потому что я и мой друг будут тестировать задание на наших ПК. –

2

Это хорошо сейчас до тех пор, как байтов и структуры упаковки сохраняются (когда у вас есть более чем один элемент данных в вашем struct) но, используя sizeof(myStruct) даст вам проблемы, когда у вас есть элементы данных в вашей структуре, которые выделяют кучную память.

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

+0

Хорошо, спасибо. –

1

Вы должны серьезно рассмотреть некоторую библиотеку сериализации. JSON очень популярен и очень легко отлаживается, потому что это текстовый формат. Google protocol buffers намного эффективнее, но требует больше усилий, чтобы заставить его работать. Существуют и другие подобные библиотеки, такие как Thrift.

+0

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

Смежные вопросы