views:

404

answers:

3

I tried the following:

int sockfd = socket(...);
listen(sockfd, 10);
accept(sockfd, ...);

None of the calls failed, and the program just started blocking as if I had called bind(). What will happen in this case? Will it just be impossible to ever receive a connection, since it has no local address or port? Or was it implicitly assigned a local address and port, and now it is listening on those? If so, how can I retrieve what those are?

A: 

I suspect you will never get a connection. You can check if there is a new socket listening by doing the equivalent of "netstat -an" on your OS before and after running the program.

I tried the same thing in C#:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Listen(1);
socket.Accept();

I get an exception on the second line which informs me in a roundabout way that a Bind is required. It of course works fine with:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 4567));
socket.Listen(1);
socket.Accept();

I tested with a Udp socket as well and same thing, Windows is not happy on the Listen call unless a binding has been done. Since the .Net socket calls are simply wrappers around Winsock this behaviour is likely to be the same for all Winsock derived libraries on Windows.

sipwiz
+4  A: 

The calls are working, but since you didn't bind the socket implicitly, the operating system or system library provided a port and default binding for you (exactly the same as when you call connect(2) without calling bind(2) first). Also, since you asked about the TCP stuff earlier, I'm assuming you're talking about internet sockets here.

Finding out what name the OS bound the socket to varies between operating systems, so you will have to look for your specific OS, but most operating systems provide a netstat or similar tool that you can use to query which applications are listening on which ports.,

As John mentions in a comment, you can use getsockname(2) to later find a socket's name. Here is a short example:

// ...

// Create socket and set it to listen (we ignore error handling for brevity)
int sock = socket(AF_INET, SOCK_STREAM, 0);
listen(sock, 10);

// Sometime later we want to know what port and IP our socket is listening on
socklen_t addr_size = sizeof(struct sockaddr_in);
struck sockaddr_in addr;
getsockname(sock, (struct sockaddr *)&addr, &addr_size);

addr will now contain the port and IP address that your socket is listening to.

Jason Coco
The getsockname() call will give you the address/port that the OS assigned.
John M
Good point, John... I will add an example code.
Jason Coco
A: 

As others mentioned, the OS will assign a port if you don't bind() one. You can use the getsockname() call after listen() to see what address/port are assigned. Then if you communicated that address/port to a client, it could connect.

So it makes sense that this works. You could write a program where this was an interesting thing to do.

John M