64

I need an app that sends an UDP packet to some network server and receives the response. The server replies to the same port number where request came from, so I first need to bind() my socket to any UDP port number.

Hardcoding the UDP port number is a bad idea, as it might be used by any other application running on the same PC.

Is there a way to bind an UDP socket to any port available? IMO it should be an effective way to quickly obtain a free port #, which is used by e.g. accept() function.

If no, then what's the best strategy to try binding and check for WSAEADDRINUSE/EADDRINUSE status: try the ports sequentially starting from from 1025, or 1025+rand(), or some other?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Soonts
  • 20,079
  • 9
  • 57
  • 130

3 Answers3

275

Another option is to specify port 0 to bind(). That will allow you to bind to a specific IP address (in case you have multiple installed) while still binding to a random port. If you need to know which port was picked, you can use getsockname() after the binding has been performed.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 35
    Binding to port 0 is the official documented way to bind to a OS-assigned random port. – Remy Lebeau Mar 01 '12 at 23:04
  • Documented where? Not that I'm saying this's wrong, I want to see an authoritative statement. – Pawel Veselov Nov 30 '13 at 02:58
  • 11
    It is in the [`bind()`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms737550.aspx) documentation: "if the port is specified as zero, the service provider assigns a unique port to the application from the dynamic client port range. On Windows Vista and later, the dynamic client port range is a value between 49152 and 65535. This is a change from Windows Server 2003 and earlier where the dynamic client port range was a value between 1025 and 5000... The application can use getsockname after calling bind to learn the address and the port that has been assigned to the socket." – Remy Lebeau Nov 30 '13 at 23:02
  • 2
    @RemyLebeau As far as I can see this is *NOT* documented on Linux, FreeBSD or Mac OS X (the documentation you cite above is from Microsoft Windows, which is hardly a canonical source for BSD networking docs). It does seem to work, however. – al45tair Jan 14 '14 at 17:22
  • 6
    @alastair: The question is tagged as `Windows` and `WinSock`, which is why I quoted the Microsoft documentation. AFAIK, binding to port 0 is documented in the 4.2BSD standard, which platform implementations are based on. – Remy Lebeau Jan 14 '14 at 19:50
  • @RemyLebeau The BSD docs are in inet(4), which doesn’t mention it. Appreciate that this question is tagged Windows/Winsock, but since it’s a generic question it probably shouldn’t be. – al45tair Jan 15 '14 at 08:52
  • 6
    In the linux kernel, the treatment of port#=0 as a request for a random assignment is considered so mundane that it's not even given a reference to specs. (net/ipv4/inet_connection_sock.c, inet_csk_get_port). – fche May 13 '14 at 00:07
  • 1
    @alastair If you can find a TCP implementation for which binding to port zero doesn't have the behaviour described here, please produce it. You won't. – user207421 May 10 '15 at 10:54
  • 3
    @EJP I’m not disputing that this works, merely pointing out that it isn’t documented behaviour aside from (AFAICT) on Windows and Solaris. – al45tair May 13 '15 at 14:16
  • 3
    @hanshenrik Linux DOES document the behavior of binding to an ephemeral port when requesting port 0. This behavior is described in https://man7.org/linux/man-pages/man7/ip.7.html. Also see the description of `EADDRINUSE` in https://man7.org/linux/man-pages/man2/bind.2.html – Remy Lebeau Dec 31 '20 at 20:06
46

Call sendto without calling bind first, the socket will be bound automatically (to a free port).

avakar
  • 32,009
  • 9
  • 68
  • 103
  • 5
    @claf implicit bind is also bind, isn't it? Both answers are useful, in my opinion. – WGH Mar 22 '14 at 15:28
  • @WGH : you are right, this behavior is documented for windows sockets (Note : If a socket is opened, a setsockopt call is made, and then a sendto call is made, Windows Sockets performs an implicit bind function call.) But I'm not sure this is the case for other implementations. Moreover, my opinion on implicit calls is that it's a bad habit. – claf Apr 01 '14 at 14:17
  • 17
    @claf you are kinda illogical. You downvoted someone's answer because of the topicstarter's(absolutely another man) choice. I agree that Remy's answer better, and he got a deserved votes, but downvoting an answer just because another one better is a nonsense. ⁺¹ to the answer for the unfair downvote. – Hi-Angel Sep 05 '14 at 12:25
  • 1
    @Hi-Angel: I just use votes and downvotes to "sort" answers, when I'm in a hurry, I usually read the accepted answer and look for vote difference between first and second answers (if second answer has more vote than accepted one than it's worth reading). This is how I use SO, at least I'm not illogical with myself. – claf Sep 09 '14 at 13:04
  • 1
    @claf well, at least you're tells the reason. You're doing good here. On the SO sometimes appears a peoples who just do a downvotes, and they have no either brain to explain a reason, either just a cowards. Or, possibly, both. You are the fine man. – Hi-Angel Sep 10 '14 at 09:36
  • 1
    @claf Upvoting because you're wrong. Both techniques will work, and this way saves you a `bind()` call. Not just for Windows either. – user207421 May 10 '15 at 10:53
  • If `sendto` fails, is the socket successfully bound then? – Daniel Chin Aug 01 '23 at 16:56
-1

I must be missing something, why don't you use the udp socket to send back data? Start with sendto and then use recvfrom function to read incoming data also you get as a bonus the address from which the data was sent, right there for you to send a response back.

Jonke
  • 6,525
  • 2
  • 25
  • 40
  • Some protocols require you to care what port number you're using on your end. For example, [TFTP](http://tools.ietf.org/html/rfc1350) clients use it to differentiate between multiple concurrent transfers from the same server. The server can't just send back from the same port, each file transfer requires the server to send from a different source port. The server does reply to the clients source address and port as you outlined though. – doug65536 May 21 '13 at 13:12
  • 1
    In my specific example, using a new socket for each transfer, then blindly doing `sendto` will implicitly select a source port, but there may be other protocols where you do care what the port number will be before you actually do `sendto`. – doug65536 May 21 '13 at 13:21
  • @doug65536 thats a valid example but the original question didn't contain any specific details of why. – Jonke May 21 '13 at 16:24