UDP receiving data on multiple ports

2019-02-10 20:42发布

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.

标签: sockets udp port
2条回答
手持菜刀,她持情操
2楼-- · 2019-02-10 21:22

The answer with select/poll method is right for UDP.

My previous answer was a mistake, due for some time I was confused by my working code, which in real life was to work with port-less protocols like ICMP and others.

However, coming back to UDP it all depends on which side you are, server or client.

When you send UDP packet you normally either bind a port you are using to the socket or an ephemeral port is assigned to it automatically upon sending the data with sendto(). So, normally later you may call recvfrom() to receive a reply, that normally is sent back to the port of your socket, which is bound or assigned. In this case with UDP you may use a single local socket and a single local port to communicate with two (and much more) different remote address and port combinations - think of something like a reverse server :-)

Also, depending on a protocol and system capabilities, you may use two sockets for one port or two sockets for a port-less protocol like ICMP - each socket in this case should receive its own copy of data received.

The above is just interesting, not practical.

Practical solution for you would be even no the proposed above select/poll between two sockets, yet a single socket with a separation by an internal protocol design - e.g. put something like channel identifier into your packets, you'll save port stack.

查看更多
看我几分像从前
3楼-- · 2019-02-10 21:27

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.

查看更多
登录 后发表回答