2010-08-16 3 views
4

Я хочу отправить массив символов через tcp-сокет в unix.Отправка массива символов C через сокет

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

typedef struct __attribute__((packed)) 
{ 
    uint8_t type; 
    uint8_t id_index; 
    char char_value[STR_MSG_MAX]; 
} a_msg; 

Просто потому, что C символ всегда 8 бит длиной. Однако после некоторого поиска в Google я обнаружил, что даже если char всегда имеет длину 8 бит, базовое представление может фактически быть 32-битным целым числом. Поэтому у меня сложилось впечатление, что char, возможно, не лучший способ представить строку в сообщении, которое будет отправлено через сокет из FreeBSd в Linux (или введите некоторые другие unixes, если вы хотите =) ...).

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

typedef struct __attribute__((packed)) 
{ 
    uint8_t type; 
    uint8_t id_index; 
    uint8_t char_value[STR_MSG_MAX]; 
} a_msg; 

или

typedef struct __attribute__((packed)) 
{ 
    uint8_t type; 
    uint8_t id_index; 
    int8_t char_value[STR_MSG_MAX]; 
} a_msg; 

Однако uint8_t это символ без знака и int8_t является знаковым символом. Стандартный символ C не является ни тем, что реализация не определена, как я ее понимаю.

Мои вопросы: Каков наилучший способ представления массива символов (строки) в C, который будет отправлен через TCP/IP в * NIX (Linux, FreeBSD и т.д.) независимо от платформы способом.

+0

Лучший способ отправить строку - это, вероятно, просто «написать» необработанную строку. Наверное, вы хотите отправить структуру, которую вы показываете, за один раз, а не только данные символа? – gnud

ответ

4

Хотя char может быть шириной более 8 бит, он должен всегда быть (равным) самым узким типом. (Так как, помимо других причин, sizeof(char) определяется как 1).

Так что, если платформа обеспечивает int8_t, то char должен быть ровно в 8 бит (с char отдельно ограничивается не менее 8 бит). Это означает, что вы также можете использовать char.

+0

Что произойдет, если я отправлю с платформы, где символ представлен, например, 32-битным int, а принимающая сторона представляет символ 8-битным типом данных? Если я отправлю 40-символьный массив, я отправлю 40 x 32 бит, но что произойдет на принимающей стороне, которые представляют его со структурой 40 x 8 бит? – Codeape

+0

@Codeape: Конечно, это проблема - но это не тот, который можно решить, используя 'int8_t', поскольку платформа с 32-разрядным символом' char' не может предоставить этот тип. В любом случае такие платформы обычно не имеют сетевых библиотек. – caf

+0

Я буду использовать массив символов. – Codeape

0

Вы не можете сказать, что вы отправляете whit c. Эта информация не передается.

Все, что вам нужно сделать, это:

char* buffer = (char*)(&a_msg); 

самым безопасным способом является использование неподписанных символов, если posssible.

+1

Ну нет. Однако это бой, представляющий данные, поэтому, если вы знаете, с другой стороны, что получилось, это еще одна история, тогда вы можете использовать свой байт-поток для чего-то другого. – Codeape

+0

Я просто понял, что вопрос был о представлении char/uchar на нескольких платформах. –

1

лично я бы что-то вроде:

typedef struct __attribute__((packed)) 
{ 
    uint8_t type; 
    uint8_t id_index; 
    uint8_t padding[2]; //this is to align to 32bit boundary 
    uint8_t char_value[STR_MSG_MAX]; 
} a_msg; 

Но он будет работать без отступа.

В C a char всегда 8 бит длиной. Таким образом, массив char всегда представляет собой массив байтов. Однако символ буква 'x' имеет 32 бита. Это можно проверить, используя оператор sizeof в символьном литерале. Вы также увидите, что все функции, которые возвращают один символ, например getch, возвращают int. Причина в том, что нам нужен способ указания End of File EOF. Это можно сделать только с использованием значения вне 8-битного диапазона.

+0

В обычной современной практике символ «char» имеет длину 8 бит. Но это не требуется стандартом - C будет работать на 6-битном или 16-битном процессоре. – bstpierre

+0

@bstpierre: * minimum *, разрешенный для символа 'char', равен 8 бит. Таким образом, 6-битный процессор должен был бы представлять 'char' с 12-битным словом, а программы C не могли бы обращаться к отдельным 6-битным ячейкам. – caf

+0

@caf - Вы правы, я опечатал персонажа выше. Предположим, 36 или 16. Спасибо за исправление. – bstpierre

0

Я думаю, что идея упаковки структуры - это путь. Я бы написал тестовый код, чтобы убедиться, что он работает. Сделайте sizeof (a_msg), чтобы увидеть, какой размер он имеет.Вы должны знать, работает ли упаковка без отправки сообщений через сокет.

+0

Хорошо. Я собираю структуру. – Codeape

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