C错误从流套接字读取数据包

时间:2013-02-08 21:21:30

标签: c sockets

我只是在玩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

3 个答案:

答案 0 :(得分: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);

VS

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);

答案 1 :(得分:1)

你的memcpy偏移是错误的。修正:

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);

答案 2 :(得分:1)

为什么所有的舞蹈都将一个结构中的东西复制到变量中,然后调整endianness和memcpy?你可以一次性dst->f1 = htons(src->f1)。只有struct来处理东西要容易得多,而不是单独使用单个字节(当然,你必须小心编译器不会潜入填充)。我认为以这种方式重做代码将解决您的问题。