UDP не получает второй раз

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

"Серверная сторона" - это компьютер, на котором работает Ubuntu 16.04. "На стороне клиента" работает LwIP на TI DSP. Вот часть кода, которая работает:

/*  find out who is out there  */

usock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if(!usock)
  {
    printf("can't create UDP socket \n");
    exit(-4);
  }

/*  si_me is local receive port  */

  memset((char *) &si_me, 0, sizeof(si_other));
  si_me.sin_family = AF_INET;
  si_me.sin_port = htons(RCVPORT);
  si_me.sin_addr.s_addr = htonl(INADDR_ANY);
  bind(usock, (struct sockaddr*)&si_me, slen);

/*  si_other is broadcast receive port */

  memset((char *) &si_other, 0, sizeof(si_other));
  si_other.sin_family = AF_INET;
  si_other.sin_port = htons(BRDCST);
  inet_aton("192.168.1.255", &si_other.sin_addr);

  setsockopt(usock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
  flags = fcntl(usock, F_GETFL);
  flags |= O_NONBLOCK;
  fcntl(usock, F_SETFL, flags);
[...]

    printf("sending %s", sndbuffer);
    if (sendto(usock, sndbuffer, 26, 0 , (struct sockaddr *) &si_other, slen) < 0)
    {
      printf("failed udp sendto\n");
      exit(-5);
    }
    clock_gettime(CLOCK_REALTIME, &rtc);
    ttime = rtc.tv_sec;
    j = 0;
    printf("waiting for response\n");
    while((j <= 0) && (ttime + 10 > rtc.tv_sec))
    {
      j = recvfrom(usock, &rcvbuffer[numBytes], 256, 0, NULL, 0);
      if(j > 0)
      {
    numBytes += j;
    break;
      }
      clock_gettime(CLOCK_REALTIME, &rtc);
    }  
  printf("got %ld bytes\n", numBytes);
  rcvbuffer[24] = 0;
  printf("received %s", rcvbuffer);

Назначение этого блока состоит в том, чтобы клиентская сторона знала, по какому IP-адресу находится сервер, и чтобы серверная сторона знала, кто там. В конечном итоге потребуется расширение для работы с несколькими клиентами, но по одному шагу за раз!

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

/*  far address from response  */

  memset((char *) &si_radar, 0, sizeof(si_radar));
  si_radar.sin_family = AF_INET;
  si_radar.sin_port = htons(LELYPORT);
  inet_aton(&rcvbuffer[7], &si_radar.sin_addr);
  printf("sending to: %s:%d\n", &rcvbuffer[7], LELYPORT);

sprintf(sndbuffer, "  %02d:%02d:%06.3f %05d %02d:%02d:%06.3f\n",
    shr, smn, seconds, i, ehr, emn, econ);
numBytes = sendto(usock, sndbuffer, 34, 0, (struct sockaddr*)&si_radar, slen);
printf("sent %s", sndbuffer);

И тогда ничего не появляется, когда я звоню:

while((numBytes < 22) && (i < 10))
{
  j = recvfrom(usock, rcvbuffer, 256, 0, NULL, 0);
  if(j > 0) numBytes += j;
  if(j < 0)
  {
     if(errno != EAGAIN)
         perror("receive error:");
  }

После этого у меня проверка часов и через 30 секунд я пытаюсь отправить заново. На wireshark я вижу исходящее сообщение от sendto(), а также ответ от LwIP/DSP. Тем не менее, recv() никогда не получает никакого ответа!

Я пытался использовать разные порты, разные сокеты, закрывать первый сокет и создавать новый сокет, и он никогда не видит ответ на втором UDP.

Я предполагаю, что есть что-то тривиально очевидное, которого я не вижу, и все различные комбинации попыток обошли это, а не решили проблему. Некоторые из этих комбинаций включают размещение &si_radar, &rlen в recvfrom() вместо NULL, 0, а также такие вещи, как

  rdrSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if(!rdrSock)
  {
    printf("can't create UDP radar socket \n");
    exit(-4);
  }
/* local address fixed */

  memset((char *) &si_me, 0, sizeof(si_other));
  si_me.sin_family = AF_INET;
  si_me.sin_port = htons(LELYPORT);
  inet_aton("192.168.1.13", &si_me.sin_addr);
  if(bind(rdrSock, (struct sockaddr*)&si_me, slen)<0) perror("bind failed");
  flags = fcntl(rdrSock, F_GETFL);
  flags |= O_NONBLOCK;
  fcntl(rdrSock, F_SETFL, flags);

а затем использовать rdrSock вместо usock. Не сделал разницы

У кого-нибудь есть идеи почему? UDP должен просто отправлять и получать данные, особенно если он входит в порт! Спасибо майк

0 ответов

Другие вопросы по тегам