Bind to a local port that is already in use
Hi,
(Development Environment => OS: Windows Vista, Compiler: Visual C++ 2005 Express Edition)
I MUST have two independent applications which use to same local port by UDP. The application 1 is a server which receives the UDP request, processes it, and sends the response. The application 2 is a sender which sends UDP packets to clients.
So, In application 2, I write the following statements between socket and bind functions:
Code:
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
int iOptVal;
int iOptLen = sizeof(int);
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) != SOCKET_ERROR) {
printf("Set SO_REUSEADD: ON\n");
}
if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR) {
printf("SO_REUSEADD Value: %ld\n", iOptVal);
}
I run the application 1, and then run the application 2.
In application 2, it shows:
Set SO_REUSEADD: ON
SO_REUSEADD Value: 1
Can't bind a socket with error code 10013
I run the application 2, and then run the application 1.
In application 1, it occurs an error on bind statement about [Address already in use : 10048].
I also write the following statements between socket and bind functions in application 1:
Code:
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
int iOptVal = 0;
int iOptLen = sizeof(int);
if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR) {
printf("SO_REUSEADD Value: %ld\n", iOptVal);
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) != SOCKET_ERROR) {
printf("Set SO_REUSEADD: ON\n");
}
if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR) {
printf("SO_REUSEADD Value: %ld\n", iOptVal);
}
I get the following result and no error occurs.
SO_REUSEADD Value: 0
Set SO_REUSEADD: ON
SO_REUSEADD Value: 1
Is this way right? :)
Thank you.
Re: Bind to a local port that is already in use
your usage of the setsockopt function is correct, however, you can't have 2 applications using the same local port.
Why do you need them to use the same port? Do both act as servers, i. e. do they get messages from clients and then answer to them? If so, you should think of using different ports. And if they are not designed as servers, it does not matter what local port they use.
HTH
Richard
Re: Bind to a local port that is already in use
setsockopt is for operating system to free your socket immediately when the socket status is closing.so,there is no time_waitting status for your socket.please reference for some books about TCP protocol
Re: Bind to a local port that is already in use
Quote:
Originally Posted by Richard.J
your usage of the setsockopt function is correct, however, you can't have 2 applications using the same local port.
Why do you need them to use the same port? Do both act as servers, i. e. do they get messages from clients and then answer to them? If so, you should think of using different ports. And if they are not designed as servers, it does not matter what local port they use.
HTH
Richard
In MSDN, it says
Since every connection is uniquely identified by the combination of local and remote addresses, there is NO problem with having two sockets bound to the same local address as long as the remote addresses are different..
But I use the same remote addresses, it seems to be okay in my testing.
Re: Bind to a local port that is already in use
But it's against the TCP protocol. We have a daemon running on port 100 right and that daemon understands some protocol X, but in the mean time if we run another daemon that binds also on port 100 and understands protocol Y what would happen? That's why modern OSs have a security mechanism to disallow binding on the same port twice.
You can take the code from one of your daemons and implement it in the other so you'll have one "super" daemon understanding both protocols.
Re: Bind to a local port that is already in use
Quote:
Originally Posted by ludakot
But it's against the TCP protocol. We have a daemon running on port 100 right and that daemon understands some protocol X, but in the mean time if we run another daemon that binds also on port 100 and understands protocol Y what would happen? That's why modern OSs have a security mechanism to disallow binding on the same port twice.
You can take the code from one of your daemons and implement it in the other so you'll have one "super" daemon understanding both protocols.
I know that:
For TCP, we are NEVER able to bind the same IP address and the same port, a completely duplicate binding.
But for UDP, I don't find any information about that.
Re: Bind to a local port that is already in use
Code:
home:~/udp# python 1.py &
[1] 23109
home:~/udp# python 1.py &
[2] 23110
home:~/udp# Traceback (most recent call last):
File "1.py", line 7, in ?
server.bind(('', PORT))
File "<string>", line 1, in bind
socket.error: (98, 'Address already in use')
[2]+ Exit 1 python 1.py
home:~/udp# cat 1.py
import socket
PORT = 10000
BUFLEN = 512
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
server.bind(('', PORT))
while True:
(message, address) = server.recvfrom(BUFLEN)
print 'Received packet from %s:%d' % (address[0], address[1])
print 'Data: %s' % message
There's your answer :)
To answer simple, you can't have the same door number in the same hallway :)
Re: Bind to a local port that is already in use
Cooker is looking for C/C++ answers for Windows Vista. What are you hoping to prove with your python posting?
Re: Bind to a local port that is already in use
Quote:
Originally Posted by MikeAThon
Cooker is looking for C/C++ answers for Windows Vista. What are you hoping to prove with your python posting?
Proving that you can't bind on the same UDP port on the same IP twice.
OSs don't matter the protocol is the same on *any* OS otherwise *nix machines can't communicate with windows machines over the internet :)
Programming language also doesn't matter because sockets are sockets, implemented in the OS.
If anyone can prove otherwise I will erase my name off my CCNA certificate and place his name instead.
Re: Bind to a local port that is already in use
I make two experiments:
- Two UDP sockets bind the same local address and port, send UDP packets to the SAME remote address for every 1 second.
- Two UDP sockets bind the same local address and port, receive UDP packets.
Programs in experiments, they calls setsockopt function to set the SO_REUSEADDR socket option for the socket before issuing the bind.
In the experiment 1, at the remote address side, I can receive all the UDP packets.
In the experiment 2, the socket which it is the first to bind will receive the UDP traffic.
I am sure that sockets which bind to the same local port and address can send UDP packets correctly.
That's all my experiments.
Re: Bind to a local port that is already in use
Those are good experiments. Thank you for sharing your results with us.
Mike
Re: Bind to a local port that is already in use
I've made Cooker's experiment #2 with TCP sockets once and it was absolutely arbitrary which server received packets. (Just wanted to let you know.)
Re: Bind to a local port that is already in use
Quote:
Originally Posted by ludakot
... you can't bind on the same UDP port on the same IP twice.
...
If anyone can prove otherwise I will erase my name off my CCNA certificate and place his name instead.
@ludakot: In view of Cooker's experiments on UDP, and Richard.J's confirmation for TCP, are you ready to relinquish that CCNA certificate?
Just teasing ;) Sorry, I couldn't resist.
Re: Bind to a local port that is already in use
Quote:
Originally Posted by MikeAThon
@ludakot: In view of Cooker's experiments on UDP, and Richard.J's confirmation for TCP, are you ready to relinquish that CCNA certificate?
Just teasing ;) Sorry, I couldn't resist.
I'll believe it when I see some running code. If that's so then apparently windows sockets have huge security issue. What stops user to bind on port 80 on some webserver and steal HTTP based usernames and passwords if it's arbitrary which server receives packets?
I don't have a windows machine to test this on, but every attempt i've done on my gentoo box has failed at the same place, I couldn't bind on the same port twice, not matter if it's UDP or TCP.
Re: Bind to a local port that is already in use
Yes, it is a security issue, but it's not unique to Windows. The issue arises in all BSD socket implementations that support the SO_REUSEADDR option. AFAIK, all implementations do so, inclusive of Linux, Sun etc.
Windows introduced the SO_EXCLUSIVEADDRUSE option to address this issue. See "Using SO_EXCLUSIVEADDRUSE" at http://msdn2.microsoft.com/en-us/library/ms740618.aspx . Here's a quote:
Quote:
The SO_EXCLUSIVEADDRUSE option prevents other sockets from being forcibly bound to the same address and port, a practice enabled by the SO_REUSEADDR option; such reuse can be executed by malicious applications to disrupt the application. The SO_EXCLUSIVEADDRUSE option is very useful to system services requiring high availability. This option is available on Microsoft Windows. The following code example illustrates setting this option.
I am not certain if other socket implementations (i.e., other than that on Windows) also have the SO_EXCLUSIVEADDRUSE option.
Mike