Неподписанный int появляется как случайное отрицательное целое число после отправки с UDP - PullRequest
0 голосов
/ 30 марта 2012

Я отправляю структуру с одним полем (unsigned int) в сетевой эмулятор, и он выводит unsigned int, но это неверно.

Если я НЕ перезапущу сетевой эмулятор, если я повторно отправлю структуру с тем же номером, это будет то же случайное целое число.Если я отправлю это число +1, я получу случайное целое число -1.

Если я перезапущу сетевой эмулятор и повторно отправлю структуру с тем же номером, он покажет другое случайное целое число.

Это структура:

struct pkt_INIT {
  unsigned int router_id;
};

Это код для отправки этой структуры:

  int sock;
  struct sockaddr_in server_addr;
  struct hostent *host;
  char send_data[1024];

  host= (struct hostent *) gethostbyname(emulator_host);

  if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("socket");
    exit(1);
  }

  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(emulator_port);
  server_addr.sin_addr = *((struct in_addr *)host->h_addr);
  bzero(&(server_addr.sin_zero),8);

  struct pkt_INIT init;
  init.router_id = router_id;
  strcpy(send_data,(char *)&init);

  sendto(sock, send_data, strlen(send_data), 0,
         (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

У меня нет кода для эмулятора сети.

Ответы [ 2 ]

1 голос
/ 30 марта 2012

Не используйте strcpy(), чтобы поместить двоичную структуру в двоичный массив. Аналогично, не используйте strlen(), чтобы получить длину структуры. Обе функции предназначены для строк и будут копировать / читать байты, пока они не встретят нулевой байт. Используйте memcpy() и sizeof() вместо:

memcpy(send_data, &init, sizeof(init)); 
sendto(sock, send_data, sizeof(init), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 

В этом случае просто избавьтесь от массива и передайте структуру непосредственно sendto():

sendto(sock, (char*)&init, sizeof(init), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 

Теперь, с учетом сказанного, есть проблема с router_id. Большинство сетевых протоколов требуют упорядочения сетевых байтов, поэтому вам может понадобиться или не потребоваться htonl(), в зависимости от того, что на самом деле ожидает эмулятор:

init.router_id = htonl(router_id); 
1 голос
/ 30 марта 2012

Вы используете: strcpy(send_data,(char *)&init);

Это действительно , что вы намеревались сделать?Вы копируете переменную структуры в массив символов.Предполагая, что вы хотите просто сделать побайтное копирование этим способом, все еще есть проблемы. init не будет иметь нулевого завершения.Поэтому последующий вызов strlen() сомнителен.

update:

Просто сохраните -1 в массиве char и преобразуйте его как целое число на стороне получателя.

send_data[0]=255; //To store -1
send_data[1]='\0'; 

Сторона получателя:

int i;
i = recv_data[0];

'i' будет иметь -1.

...