0

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
4

3 に答える 3

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);
于 2013-02-08T21:24:22.930 に答える
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);
于 2013-02-08T21:24:04.430 に答える
1

ある構造体から変数に何かをコピーしてから、エンディアンと memcpy を調整するのはなぜですか? あなたはただdst->f1 = htons(src->f1)一度に行うことができます。個々のバイトをいじるのではなく、 sだけで何かを処理する方がはるかに簡単ですstruct(確かに、コンパイラがパディングをこっそり入れないように注意する必要があります)。そのようにコードをやり直すと、問題が解決すると思います。

于 2013-02-08T22:00:26.387 に答える