ОТПРАВКА СТРУКТОВ с использованием TCP-сокетов - PullRequest
0 голосов
/ 19 апреля 2011

Я читаю файл в структурах, затем записываю их на сервер. Вот фрагмент кода:

struct b{
uint16_t num;
char str[10];
} x;
 struct a{
 uint32_t pid;
 char str1[10];
 char str2[10];

} y;

while(fscanf(fp,"%s",buff) != EOF)
while(1){
c = getchar();
if (c == '\n')
break;

else
buff[i]= c ;
i++;

write(fd, &b,sizeof(b))

Формат текстового файла

  • 123
  • George
  • Lee

  • Как мне прочитать и сохранить файл в каждой структуре?

  • Когда я пишу на сервер, это выглядит как

  • запись (fd, & a, sizeof (struct a)). написать (fd, & b, sizeof (struct b))? Как обеспечить правильное заполнение, порядковый номер

Вот так я запускаю файл: /a.out IP PORT

Ответы [ 2 ]

0 голосов
/ 19 апреля 2011

Не используйте send / recv (сокеты) или read / write (файловые дескрипторы) со структурами.Это практически гарантированно сломать позже.Среди других проблем, заполнение и / или выравнивание элементов структуры может меняться в зависимости от компилятора, параметров компиляции и среды.

Вместо этого, упорядочите данные в независимый формат (например, текст) и отправьтетот.Если данные должны быть абсолютно одинаковыми с обеих сторон, закодируйте их в базу 64 и добавьте контрольную сумму.

Если вам абсолютно необходимо передавать двоичные данные, не забудьте преобразовать каждый из элементов структуры в сетевой порядок байтов (man byteorder) и отправить каждый из них по отдельности.

0 голосов
/ 19 апреля 2011

Когда вы говорите «прочитать и сохранить файл для каждой структуры», не могли бы вы прояснить этот вопрос?

Чтобы обеспечить правильное заполнение и порядковый номер, вам нужно сделать две вещи:

  1. Отправка структуры по одному полю за раз. Это боль. Поскольку вы объявляете каждый член структуры как тип uint16_t (и из этого семейства), sizeof () даст вам одинаковый ответ для всех платформ.

  2. Чтобы обеспечить порядок байтов, вы должны использовать семейство порядка хост-сеть. См .: http://www.gnu.org/s/hello/manual/libc/Byte-Order.html

  3. Когда вы делаете это, вы должны использовать htons() (короткое замыкание между сетями) при отправке и затем ntohs() (короткое замыкание между сетями) при получении. Для каждого члена вашей структуры.

Часто люди игнорируют это; если обе машины являются современными блоками Intel, что справедливо для подавляющего большинства из нас, вы можете получить код, который вы используете для отправки структур. Но, как вы упомянули, это не гарантирует гарантию и бесконечность!

Вы также можете использовать директивы # pragma pack () GNU для указания того, как следует обрабатывать заполнение. Это работает, если вы можете полагаться на набор инструментов GNU как для своего клиента, так и для сервера, поскольку это не является частью спецификации C.

...