2013-02-08 2 views
0

Я просто играю с потоковыми сокетами на C, но у меня возникла проблема с чтением пакета данных, возвращаемого из серверного приложения. В приведенном ниже коде показана структура, которая используется на стороне клиента и сервера.C Ошибка чтения пакета из потокового сокета

struct packet 
{ 
    uint16_t f1; 
    uint16_t f2; 
    uint32_t f3; 
    uint16_t pf1; 
    uint32_t pf2; 
}; 

стороны сервера для отправки:

char buffer[14]; 
struct packet myPacket; 

myPacket.f1 = 2321; 
myPacket.f2 = 4423; 
myPacket.f3 = 2134; 
myPacket.pf1 = 765; 
myPacket.pf2 = 9867; 

htonPacket(myPacket, buffer); 

Функция для упаковки данных в буфер.

void htonPacket(struct packet h, char buffer[14]) { 
    uint16_t u16; 
    uint32_t u32; 

    u16 = htons(h.f1); 
    memcpy(buffer+0, &u16, 2); 

    u16 = htons(h.f2); 
    memcpy(buffer+2, &u16, 2); 

    u32 = htonl(h.f3); 
    memcpy(buffer+4, &u32, 4); 

    u16 = htons(h.pf1); 
    memcpy(buffer+8, &u16, 2); 

    u32 = htonl(h.pf2); 
    memcpy(buffer+10, &u32, 4); 
} 

стороне клиента для распаковки и печати:

void ntohPacket(struct packet* h, char buffer[14]) { 
    uint16_t u16; 
    uint32_t u32; 

    memcpy(&u16, buffer+0, 2); 
    h->f1 = ntohs(u16); 

    memcpy(&u16, buffer+2, 2); 
    h->f2 = ntohs(u16); 

    memcpy(&u32, buffer+4, 4); 
    h->f3 = ntohl(u32); 

    memcpy(&u16, buffer+6, 2); 
    h->pf1 = ntohs(u16); 

    memcpy(&u32, buffer+8, 4); 
    h->pf2 = ntohl(u32); 
} 

Печать распакованы данные:

printf("myPacket.f1: %d\n", myPacket.f1); 
printf("myPacket.f2: %d\n", myPacket.f2); 
printf("myPacket.f3: %d\n", myPacket.f3); 
printf("myPacket.pf1: %d\n", myPacket.pf1); 
printf("myPacket.pf2: %d\n", myPacket.pf2); 

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

myPacket.f1: 2321 
myPacket.f2: 4423 
myPacket.f3: 2134 
myPacket.pf1: 2134 
myPacket.pf2: 50135040 
+1

Почему все танцы с копированием материала из одной структуры в переменную, а затем настраивают континент и memcpy? Вы могли бы просто сделать 'dst-> f1 = htons (src-> f1)' за один раз. Намного проще иметь '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Я думаю, что повторный код вашего кода устранит вашу проблему. – vonbrand

+0

Я учусь, и я просто расширялся на примере, который я нашел в пакете. Спасибо за предложение. – dsell002

+0

@vonbrand: опубликуйте это как ответ, и вы получите + голос от меня;) – nneonneo

ответ

2

Ну, вы используете различные смещения для memcpy операций, поэтому, конечно, вы получите мусор ...

memcpy(buffer+0, &u16, 2); 
memcpy(buffer+2, &u16, 2); 
memcpy(buffer+4, &u32, 4); 
memcpy(buffer+8, &u16, 2); 
memcpy(buffer+10, &u32, 4); 

против

memcpy(&u16, buffer+0, 2); 
memcpy(&u16, buffer+2, 2); 
memcpy(&u32, buffer+4, 4); 
memcpy(&u16, buffer+6, 2); 
memcpy(&u32, buffer+8, 4); 

Ваших последних строк в ntohPacket следует читать

memcpy(&u16, buffer+8, 2); 
h->pf1 = ntohs(u16); 

memcpy(&u32, buffer+10, 4); 
h->pf2 = ntohl(u32); 
+0

Doh, спасибо. После исправления, однако, появилось что-то более интересное. Теперь последнее значение немного отличается от того, что я ожидаю. myPacket.pf2: 9728 Когда я отправляю 9867. – dsell002

+1

Я бы просто сделал то, что предложил @vonbrand (в его комментарии). Поддержание всех этих показателей неизбежно вызовет у вас неисчислимую боль. – nneonneo

1

Ваши неправильные смещения неверны. Исправлено:

memcpy(&u16, buffer+0, 2); 
h->f1 = ntohs(u16); 

memcpy(&u16, buffer+2, 2); 
h->f2 = ntohs(u16); 

memcpy(&u32, buffer+4, 4); 
h->f3 = ntohl(u32); 

memcpy(&u16, buffer+8, 2); <-- here 
h->pf1 = ntohs(u16); 

memcpy(&u32, buffer+10, 4); <-- here 
h->pf2 = ntohl(u32); 
1

Почему все танцы с копированием материала из одной структуры в переменную, а затем корректируют континент и memcpy? Вы могли бы просто сделать dst->f1 = htons(src->f1) за один раз. Намного проще иметь struct s, чтобы обрабатывать вещи, а не дурачиться с отдельными байтами (конечно, вы должны быть осторожны, чтобы компилятор не проникал в дополнение). Я думаю, что повторный код вашего кода устранит вашу проблему.

+0

+1, это лучший совет. – nneonneo

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