Search code examples
socketsudpport

UDP receiving data on multiple ports


Is it possible to receive data with recvfrom on 2 ports? I have a port which I use for user requests and another port for chat messages. Is it possible to bind two sockets, with different ports and receive data with one recvfrom()?

Regards

EDIT Does this code work?

int socket_fd,socket_fd2;
struct sockaddr_in addr, chat_addr;

addr.sin_family = AF_INET;
addr.sin_port = htons(1234);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");

chat_addr.sin_family = AF_INET;
chat_addr.sin_port = htons(4321);
chat_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

bind(socket_fd2, (struct sockaddr *) &chat_addr, sizeof(struct sockaddr_in));
bind(socket_fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));

So I want to receive data on two different ports.


Solution

  • No, it's not possible to read from both sockets using a single call to recvfrom, since that function only takes a single socket file descriptor parameter.

    You either need a thread per port, or a mechanism (e.g. select, poll) to tell which sockets have data waiting to be read.

    In the latter case, once you know which sockets have pending data you can then call recvfrom on that specific socket to get the data you need, e.g.:

    // set up select parameters
    fd_set socks;
    FD_ZERO(&socks);
    FD_SET(socket_fd, &socks);
    FD_SET(socket_fd2, &socks);
    
    // find out which sockets are read - NB: it might be both!
    int nsocks = max(socket_fd, socket_fd2) + 1;
    if (select(nsocks, &socks, (fd_set *)0, (fd_set *)0, 0) >= 0) {
         if (FD_ISSET(socket_fd, &socks)) {
              // handle socket 1
              recvfrom(socket_fd, ...);
         }
         if (FD_ISSET(socket_fd2, &socks)) {
              // handle socket 2
              recvfrom(socket_fd2, ...);
         }
    }
    

    NB: this is just a rough and ready sample - real code would have error checking, etc.