Здравствуйте!Есть заголовок пакета следующей структуры:
1-й байт - тип протокола = 11
2-й байт - тип пакета = 1
3-4 длина пакетаВсе поля идут в сетевом представлении.
Как сделать поля в сетовом представлении?
Мой вариант:
char head[4] = {htons(11),htons(1),htons(0),htons(0)}; // 3-й 4-й пока не важныconst size_t PACKET_SIZE=8;
char* packet = new char[PACKET_SIZE];memcpy(packet,head,sizeof(head));
for(unsigned int i=0; i<PACKET_SIZE;i++)
cout << ntohs((int)packet[i]); // Здесь почему-то 00000..delete packet;
>Здравствуйте!
>
>Есть заголовок пакета следующей структуры:
>1-й байт - тип протокола = 11
>2-й байт - тип пакета = 1
>3-4 длина пакета
>char head[4] = {htons(11),htons(1),htons(0),htons(0)}; // 3-й 4-й пока не важныага, ты посмотри сначала на определение функции!
uint16_t htons(uint16_t hostshort);ДВА байта! чего собственно ты там преобразовываешь?
вот длину пакета надо! тока не так как у тебя, а сразу всю длину и
и хеадер делай не массивом, а структурой!
>[оверквотинг удален]
>>Есть заголовок пакета следующей структуры:
>>1-й байт - тип протокола = 11
>>2-й байт - тип пакета = 1
>>3-4 длина пакета
>>char head[4] = {htons(11),htons(1),htons(0),htons(0)}; // 3-й 4-й пока не важны
>
>ага, ты посмотри сначала на определение функции!
>uint16_t htons(uint16_t hostshort);
>
>ДВА байта! чего собственно ты там преобразовываешь?Спасибо! Я это видел (man htons).
Просто я плохо представляю как это должно выглядеть.Если можете, то подскажите пожалуйста.
Есть структура Header:
Так?
struct Header
{
u_char* type_protocol; //тип протокола
u_char* type_packet; // тип пакета
u_char* llength; // длина пакета.
u_char* hlength;
}//Длина пакета 3-4 байт
Зачем 3-4 байт? Старший, младший?int main()
{
Header* pheader = new Header;Длина известна путь она = LEN
1) далше надо сделать поля заголовка в сетевом представлении
2) Прикрепить тело пакета
2) Затем этот пакет (header+body) послать с помощью send() в сокет
delete pheader;
}
>[оверквотинг удален]
>
>Так?
>struct Header
>{
>u_char* type_protocol; //тип протокола
>u_char* type_packet; // тип пакета
>u_char* llength; // длина пакета.
>u_char* hlength;
>}
>неа, смотри elvenic все написал.
>Здравствуйте!
>
>Есть заголовок пакета следующей структуры:
>1-й байт - тип протокола = 11
>2-й байт - тип пакета = 1
>3-4 длина пакета...
>Мой вариант:
>char head[4] = {htons(11),htons(1),htons(0),htons(0)}; // 3-й 4-й пока не важныTак как бы сделали нельзя. Для байтов вообще нет htonX функции - порядок битиков в байте не имеет никакого отношения к host/network _byte_ order :). Т.е, целые значения длинний в 8 бит в пакете не надо преобразовывать.
А вот 16-битовая длинна пакета - ее необходимо преобразовать _одним_ вызовом htons() целиком.
Один из правильных вариантов - так:
char head[4];
head[0] = 11;
head[1] = 1;
*((uint16_t *)(&head[2])) = htons(real_length);Красивее будет определить структуру для пакета, но нужно ее обязательно определять как packed, что для разных компиляторов делается по разному - для gcc, например, нужно добавить __attribute__((packed)) (подробнее - google 'gcc packed'):
#ifdef __GNUC__
struct packet {
uint8_t prot_type;
uint8_t pkt_type;
uint16_t pkt_length;
...
} __attribute__((packed));
#endifstruct packet pkt;
pkt.prot_type = 11;
pkt.pkt_type = 1;
pkt.pkt_length = htos(real_length);
Огромное Вам Спасибо!
Если позволите еще вопрос:Как вот эту структуру pkt передать в сокет, т.е. меня интересут только функция send или write
ssize_t send(int s, const void *msg, size_t len, int flags);
Что нужно подставить вместо msg и len?
>Как вот эту структуру pkt передать в сокет, т.е. меня интересут только
>функция send или write
>
>ssize_t send(int s, const void *msg, size_t len, int flags);
>
>Что нужно подставить вместо msg и len?Видимо, что-то вроде этого:
struct my_struct data;
// ... do something with struct
send(my_socket, (char*)(&data), sizeof(my_struct), 0);The receiver should do something like:
struct my_struct remote_data;
recv(my_socket, (char*)&remote_data, sizeof(my_struct), 0);
всё верно
>всё верноага, но если это и будет работать, то с большими глюками :)
>>всё верно
>
>ага, но если это и будет работать, то с большими глюками :)
>Тогда, как правильно?
>>>всё верно
>>
>>ага, но если это и будет работать, то с большими глюками :)
>>
>
>Тогда, как правильно?кхм. все зависит от того чего ты хочешь получить.
send худо бедно работать будет.
а вот recv, он обладает такой особенностью что возвращает данные которые пришли, и есть большая вероятность того что вернется не полный буфер в recv, посланный в send.
таким образом, надо будет вызывать recv в цикле. до тех пор, пока не примется весь необходимый буфер.можно сделать это используя флаг MSG_WAITALL
ну а дальше сам пофантазируй.
>[оверквотинг удален]
>send худо бедно работать будет.
>а вот recv, он обладает такой особенностью что возвращает данные которые пришли,
>и есть большая вероятность того что вернется не полный буфер в
>recv, посланный в send.
>таким образом, надо будет вызывать recv в цикле. до тех пор, пока
>не примется весь необходимый буфер.
>
>можно сделать это используя флаг MSG_WAITALL
>
>ну а дальше сам пофантазируй.Я использую send и recv вместо write read, как раз из-за того, что есть возможность установить флаги.
Спасибо!