0

I'm lost, but the title sums it up. I'm trying to make a UDP server using netster, but for whatever reason, I'll get data from the client but not the other way around. I suspect it has something to do with clientaddr due to getting an error "sendto: Address family not supported by protocol," but I've looked over multiple examples and this seemed like the documented way to use the struct.

I really cannot pinpoint the issue here so I'll show all my code

void chat_server(char* iface, long port, int use_udp)
{
   struct addrinfo hints;
   struct addrinfo *results, *rp;
   char buff4[INET_ADDRSTRLEN];
   void* raw_addr;
   int sfd = 0, valread, connectfd;
   short end = 0;

   char cport[7];
   struct sockaddr_in servaddr, clientaddr;
   socklen_t addrlen;
   char* rescbuff;
   sprintf(cport, "%ld", port);
   size_t count = 0;

   //TCP & UDP FLAGS
   if(use_udp)
   {
      hints.ai_protocol = IPPROTO_UDP;
      hints.ai_family   = AF_UNSPEC;
      hints.ai_socktype = SOCK_DGRAM;
   }
   else
   {
      hints.ai_protocol = IPPROTO_TCP;
      hints.ai_family   = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
   }
   hints.ai_flags     = AI_PASSIVE;
   hints.ai_canonname = NULL;
   hints.ai_addr      = NULL;
   hints.ai_next      = NULL;


   //get IP address and socket from server
   if(getaddrinfo(iface, cport, &hints, &results))
   {
      perror("getaddrinfo");
      exit(-1);
   }
   for(rp = results; rp != NULL; rp = rp->ai_next)
   {
      sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
      if(sfd == -1) continue;

      if(rp->ai_family == AF_INET)//(results->ai_family == AF_INET)
      {
         struct sockaddr_in* tmp = (struct sockaddr_in*)rp->ai_addr;
         raw_addr = &(tmp->sin_addr);
         inet_ntop(AF_INET,  raw_addr, buff4, INET_ADDRSTRLEN);
         break;
      }
   }

   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
   servaddr.sin_port = htons(port);

   //bind
   valread = bind(sfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
   if(valread == -1)
if(valread == -1)
   {
      perror("bind server");
      exit(-1);
   }
 addrlen = sizeof(clientaddr);
      rescbuff = malloc(MAX_S*sizeof(char*));
      do
      {
         //get client IP + count connections starting at 0
         //memset(&clientaddr, 0, sizeof(clientaddr));

         struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&clientaddr;
         struct in_addr ipAddr = pV4Addr->sin_addr;
         char str[INET_ADDRSTRLEN];
         inet_ntop( AF_INET, &ipAddr, str, INET_ADDRSTRLEN );

         clientaddr.sin_family = AF_INET;
         //clientaddr.sin_addr.s_addr = inet_addr(str);
         do //communicate loop
         {
            socklen_t len;
            memset(rescbuff, 0, MAX_S);
            valread = 0;
            //get message
            valread = recvfrom(sfd, rescbuff, MAX_S, 0, (struct sockaddr*)&clientaddr, &len);
            if( valread == -1)
            {
               perror("recvfrom");
               exit(-1);
            }

            //acknowledge
            printf("got message from('%s', %d)\n",str, servaddr.sin_port);
            printf("message %s\n", rescbuff);


            //reply to message
            printf("try1\n");
            //valread = sendto(sfd, rescbuff, strlen(rescbuff), 0, ( struct sockaddr*)&clientaddr, sizeof(clientaddr));
            valread = sendto(sfd, "hello\n", 20, 0, (struct sockaddr*)&clientaddr, sizeof(clientaddr));
            if(valread == -1)
            {
               perror("sendto");
               exit(-1);
            }
            printf("bytes sent: %d\n", valread);
           
         }
         while(1);

         if(end) break;
      }
      while(1);

   close(sfd);
  • Looks like the `len` value you're passing the address of to `recvfrom` is uninitialized. It is both an input and an output, and if its too small, `clientaddr` will end up truncated. – Chris Dodd Oct 18 '22 at 21:27
  • `valread = bind(sfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); if(valread == -1) if(valread == -1)` why is the value of valread tested twice – user3629249 Oct 20 '22 at 00:26
  • `while(1);` wiil loop forever – user3629249 Oct 20 '22 at 00:40

0 Answers0