• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
select() not working with UDP
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

select() not working with UDP


  • Subject: select() not working with UDP
  • From: email@hidden
  • Date: Mon, 29 Jun 2009 23:48:56 -0700

Hello,

My simple UDP packet echoer works without using select().   But, I need to use select() as the complexity of my app increases.

The problem is that select() only returns after the timeout, but not when any UDP data has arrived.

Thanks for any input!

The code is below:

#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/select.h>
#include <fcntl.h>


#define PORTIN  "4701"    // the port users will be connecting to
#define PORTOUT "4700"    // the port users will be connecting to

#define    PORTINNUM    4701
#define    PORTOUTNUM    4700

#define MAXBUFLEN 32768

int sockfdIn,sockfdOut;
struct addrinfo *servinfoOutSelect;


void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

// prepares for udp input using getaddrinfo
// this method works for recvfrom but select does not work.
int prepIn(void) {
    struct addrinfo hints, *servinfoIn, *servinfoInSelect;
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, PORTIN, &hints, &servinfoIn)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(servinfoInSelect = servinfoIn; servinfoInSelect != NULL; servinfoInSelect = servinfoInSelect->ai_next) {
        if ((sockfdIn = socket(servinfoInSelect->ai_family, servinfoInSelect->ai_socktype,
                servinfoInSelect->ai_protocol)) == -1) {
            perror("listener: socket");
            continue;
        }

        if (bind(sockfdIn, servinfoInSelect->ai_addr, servinfoInSelect->ai_addrlen) == -1) {
            close(sockfdIn);
            perror("listener: bind");
            continue;
        }

        break;
    }

    if (servinfoInSelect == NULL) {
        fprintf(stderr, "listener: failed to bind socket\n");
        return 2;
    }

    freeaddrinfo(servinfoIn);
   
    return 0;
}

int prepOut(void) {
     struct addrinfo hints, *servinfoOut;
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    if ((rv = getaddrinfo("localhost", PORTOUT, &hints, &servinfoOut)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and make a socket
    for(servinfoOutSelect = servinfoOut; servinfoOutSelect != NULL; servinfoOutSelect = servinfoOutSelect->ai_next) {
        if ((sockfdOut = socket(servinfoOutSelect->ai_family, servinfoOutSelect->ai_socktype,
                servinfoOutSelect->ai_protocol)) == -1) {
            perror("talker: socket");
            continue;
        }

        break;
    }

    if (servinfoOutSelect == NULL) {
        fprintf(stderr, "talker: failed to bind socket\n");
        return 2;
    }
   
    return 0;
}

int echo(void)
{
    struct {long global;short local;} packetCount;

    int numbytes;
    struct sockaddr_storage their_addr;
    char buf[MAXBUFLEN];
    socklen_t addr_len;
   
#ifdef USE_SELECT
   
    struct timeval tv;
    fd_set readfds;

    tv.tv_sec = 1;
    tv.tv_usec = 0;

    FD_ZERO(&readfds);
    FD_SET(sockfdIn, &readfds);
#endif
   
    packetCount.global = packetCount.local = 0;
       
    for(;;) {
#ifdef USE_SELECT
        while (!select(sockfdIn+1, &readfds, NULL, NULL, &tv))
                printf("still waiting %d\n",secCount++);
               
        if (FD_ISSET(sockfdIn, &readfds)) {
#endif

            addr_len = sizeof their_addr;
            if ((numbytes = recvfrom(sockfdIn, buf, sizeof(buf), 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
                perror("recvfrom");
                exit(1);
            }
            packetCount.global++;
            packetCount.local++;
            if (packetCount.local==100){
                printf("%d\n",packetCount.global);
                packetCount.local = 0;
            }
            if ((numbytes = sendto(sockfdOut, buf, numbytes, 0,servinfoOutSelect->ai_addr, servinfoOutSelect->ai_addrlen)) == -1) {
                perror("talker: sendto");
                exit(1);
            }
#ifdef USE_SELECT
         }
#endif
    }

    close(sockfdIn);

    return 0;
}


int main (int argc, char * const argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
   
    prepIn();
    prepOut();
    echo();
   
    return 0;
}

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: select() not working with UDP
      • From: Quinn <email@hidden>
  • Prev by Date: Re: Peer-to-Peer Ports
  • Next by Date: Re: select() not working with UDP
  • Previous by thread: Re: Peer-to-Peer Ports
  • Next by thread: Re: select() not working with UDP
  • Index(es):
    • Date
    • Thread