How come my UDP socket has a separate port for incoming and outgoing?

Started by
3 comments, last by rip-off 14 years, 1 month ago
I am testing UDP on the localhost on Windows. I create the Server Socket it like this

::socket ( AF_INET, SOCK_DGRAM, 0 ) ;

sockaddr_in sockaddr_ino ;
sockaddr_ino.sin_family = AF_INET ;
sockaddr_ino.sin_port = htons ( 5000 ) ;
sockaddr_ino.sin_addr.s_addr = htonl ( INADDR_ANY ) ;
::memset ( & sockaddr_ino.sin_zero, 0, sizeof sockaddr_ino.sin_zero ) ;

::bind ( Socketo, reinterpret_cast<sockaddr *> ( & sockaddr_ino ),
		sizeof sockaddr_ino ) ;



The Client also creates a socket but does not do bind(). The Client successfully sends Packets to 5000. And I use the Clientsockaddr_ino of recvfrom to reply back to the Client. The Server successfully replies to the Client. But then the Clientsockaddr_ino.sin_port in the Client side recvfrom is not 5000, but something like 34835, which means I cannot use the exact same handling Code in the Client. The Packets sent to 34835 are lost, even though they were sent by the Server Socket. Why not design recvfrom to return 5000?
Advertisement
Only one process can bind to a port at a time. It is normal for the client to pick a "random" port (typically, you ask your networking API for port 0 and it will give you a random one for you). The server must store the ipaddress/port combination for each client. With NATs, you have no real choice, you cannot depend on the client picking a given port in general.
Forget about it. 34835 is actually 5000 in network order. I have a huge logical bug in my Code. The same Code will work for Client and Server now.
Quote:Only one process can bind to a port at a time


That's not actually true.

First, the same port may easily be re-used for client ports when the destination is a different IP address than the IP address used the first time.

Second, with the SO_REUSEADDR TCP option, you can bind to the same port even when a previous process is still in waiting state, for listening purposes. The previous process/socket does not need to be dead.

Third, you can also fork() after binding, and have more than one process bound to the same port. This works for listen and accept as well as reading/writing. However, individual ordering between the different sockets bound to the same port (or connection, for read/write) is not guaranteed or well defined. (But for multi-processing accept() servers, it doesn't much matter)
enum Bool { True, False, FileNotFound };
I was really talking only about listening sockets, but I think I misinterpreted the original question anyway - I assumed it was the lassic case where the client was forcing a particular port after only skimming the original post. In any case, as you demonstrated it is possible to have a listening socket shared between multiple processes.

Apologies for the incorrect information. [embarrass]

This topic is closed to new replies.

Advertisement