0

次の構造体を使用して、受信したデータを入れようとしています:

typedef struct packet {
  uint8_t magic;
  uint8_t version;
  uint16_t body_length;
  char *body;
} packet;

これは印刷機能です。

void displayPacket (struct packet p){
  printf("Magic : %u\n",p.magic);
  printf("Version : %u\n",p.version);
  printf("Body Length: %d\n",ntohs(p.body_length));
  printf("Body : %s\n",p.body);
}

私のメインでは、受信したデータを私の構造に保存するためにこれを試みています:

unsigned char reply[1024];
  struct packet reply_packet;
  reply_packet.body = malloc(1021);
  reply_packet.body[1020] = '\0';
  rc = recvfrom(s,&reply_packet,sizeof(reply_packet),0,NULL,NULL);
  displayPacket(reply_packet);
  free(reply_packet.body);
  close(s);

出力:

Magic : 95
Version : 1
Body Length: 1008
[1]    4741 segmentation fault  ./network

Magic、Version、Body Length は、パケットの先頭の予期される出力です。プロトコルの後に他のピアが続くため、パケットの最大サイズは 1024 バイトです。

ただし、displayPacket 関数、より正確には次の行によって引き起こされるセグメンテーション違反があります。

printf("Body : %s\n",p.body);

役立つ場合、これは valgrind の出力です。

==4886== Invalid read of size 1
==4886==    at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4886==    by 0x4E994D2: vfprintf (vfprintf.c:1643)
==4886==    by 0x4EA0F25: printf (printf.c:33)
==4886==    by 0x108EFD: displayPacket (network.c:143)
==4886==    by 0x1090FF: main (network.c:189)
==4886==  Address 0x3030000000000000 is not stack'd, malloc'd or (recently) free'd
==4886== 
==4886== 
==4886== Process terminating with default action of signal 11 (SIGSEGV)
==4886==  General Protection Fault
==4886==    at 0x4C32CF2: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4886==    by 0x4E994D2: vfprintf (vfprintf.c:1643)
==4886==    by 0x4EA0F25: printf (printf.c:33)
==4886==    by 0x108EFD: displayPacket (network.c:143)
==4886==    by 0x1090FF: main (network.c:189)

それはかなり些細なことのように思えますが、何時間も私を悩ませてきました...

予想される出力は、パケット内の残りのコンテンツのコンテンツです。これまでのところ、私はそれを行うことができました。

この問題を解決するために考えられる解決策は何ですか?

ありがとう。

編集1:

次のように構造を変更して、セグメンテーション違反の問題を解決しました。

typedef struct packet {
  uint8_t magic;
  uint8_t version;
  uint16_t body_length;
  char body[1021];
} packet;

そして残りのコード:

unsigned char reply[1024];
  struct packet reply_packet;
  reply_packet.body[1020] = '\0';
  rc = recvfrom(s,&reply_packet,sizeof(reply_packet),0,NULL,NULL);
  printf("body[0] %d\n",reply_packet.body[0]);
  displayPacket(reply_packet);
  close(s);

displayPacket は変更されていません。

4

1 に答える 1