views:

386

answers:

3

In C++, when I run (red alert! pseudo-code)

bind(s1, <local address:port1234>)
bind(s2, <local address:port1234>)

on two different UDP sockets (s1 and s2 each created with a call to socket()) I get problems. In Linux (Ubuntu), the double binding seems to be fine. In Windows, however, the double binding fails, and the call to bind() the second time for the same address returns != 0.

I want to get the behavior I have on Windows on my Linux machine. Are there some settings I can work to get a "port busy" on Linux?

A: 

Are you sure about that? According to man 7 ip on my Linux box (fedora 9):

When a process wants to receive new incoming packets or connections, it should bind a socket to a local interface address using bind(2). Only one IP socket may be bound to any given local (address, port) pair.

There is no mention of an exception for UDP binding in either man 7 ip or man 7 udp. (This does not prove anything, but non-documented behaviour in something as basic as this is ... surprising.)

Stephen C
+2  A: 

That's not the behaviour I get on Linux. When I run the following test program, the second bind call fails with EADDRINUSE:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main()
{
    int s1, s2;
    struct sockaddr_in sa = {
        .sin_family = AF_INET,
        .sin_port = 0x5555,
        .sin_addr.s_addr = INADDR_ANY };

    s1 = socket(PF_INET, SOCK_DGRAM, 0);
    s2 = socket(PF_INET, SOCK_DGRAM, 0);
    if (bind(s1, (struct sockaddr *)&sa, sizeof sa) < 0)
        perror("bind 1");
    if (bind(s2, (struct sockaddr *)&sa, sizeof sa) < 0)
        perror("bind 2");

    return 0;
}
caf
+1 for code example (I was about to post one, but won't now :-P), but a small nit: `AF_INET` should be used for the address family (i.e., in the `sin_family` field).
Chris Jester-Young
Personally I use `AF_INET` in the `socket` call too---the Open Group Base Specification doesn't actually have any `PF_*` constants---but I can see more of a case for "lenience" for `socket` and other non-address usages.
Chris Jester-Young
Right you are sir, updated (the Linux man pages say to use the `PF_` constants for the argument to `socket()`, but I'm sure there's no practical difference).
caf
+3  A: 

Please see bind and setsockopt. Unless you have invoked setsockopt with SO_REUSEADDR, then your invocation of bind with the same address should result in failure with EADDRINUSE.

Michael Aaron Safyan
You're right on the money! SO_REUSEADDR doesn't work the same way in Windows and Linux (BSD-sockets?).
Jonas Byström
SO_REUSEADDR doesn't let you bind to an endpoint twice, though. Its purpose is to override the TIME_WAIT state after you close a TCP socket. Normally the OS keeps a TCP socket in TIME_WAIT for a few minutes to pick up any "late" packets that haven't arrived yet. If you try to open a new socket you get EADDRINUSE unless you specify SO_REUSEADDR which kills the TIME_WAIT socket.
John Kugelman