Author |
Topic: "Address already in use" errors |
|
EricJ member offline |
|
posts: |
50 |
joined: |
02/22/2007 |
from: |
CA |
|
|
|
|
|
"Address already in use" errors |
How many sockets can an application open concurrantly? Let's take a look at the following code:
String HOST = "myServer";
int PORT = 1234;
int NUM_OF_CONNECTION = 1000;
InetAddress addr = InetAddress.getByName(HOST);
Socket socket = null;
for(int i=0; i<NUM_OF_CONNECTION; i++){
try{
socket = new Socket(addr, PORT);
}catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
doSomethingWithThisConnection(socket);
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
}
Once NUM_OF_CONNECTION reaches certain number around 5000, you most likely get somethings like:
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
|
|
|
|
|
|
|
EricJ member offline |
|
posts: |
50 |
joined: |
02/22/2007 |
from: |
CA |
|
|
|
|
|
Why? |
This means that you are out of TCP/IP connections on your machine.
The reson for running out of available ports is that if you creates a lot of connection at a rapid rapid rate, the system does no have enough time to clean up the TIME_WAIT sockets. Eventually, the ports numbers for those TIME_WAIT socks run out, and your JVM crashes.
|
|
|
|
|
|
|
EricJ member offline |
|
posts: |
50 |
joined: |
02/22/2007 |
from: |
CA |
|
|
|
|
|
How to Fix It? |
The TCP/IP layer has a default maximum connections allowed in the TIMED_WAIT state. To remedy this, modify or create the following registry keys:
TcpTimedWaitDelay, sets TIME_WAIT parameter to 30 seconds, default is 240. MaxUserPort, sets maximum open ports to 65534, default is 5000
|
|
|
|
|
|
|
EricJ member offline |
|
posts: |
50 |
joined: |
02/22/2007 |
from: |
CA |
|
|
|
|
|
Another way to fix TIME_WAIT |
What's behind the scene?
RFC 793 TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.
RFC 793 sets the TIME-OUT to be twice the Maximum Segment Lifetime, or 2MSL. Since MSL, the maximum time a packet can wonder around Internet, is set to 2 minutes, 2MSL is 4 minutes. Since there is no ACK to an ACK, the active closer can't do anything but to wait 4 minutes if it adheres to the TCP/IP protocol correctly, just in case the passive sender has not received the ACK to its FIN (theoretically).
Another way to fix TIME_WAIT
The workaround solution is to ignore the TIME_WAIT by using SO_REUSEADDR option.
[JAVA DOC]:
setReuseAddress(boolean on) throws SocketException
Enable/disable the SO_REUSEADDR socket option.
When a TCP connection is closed the connection may remain in a timeout state
for a period of time after the connection is closed (typically known as the
TIME_WAIT state or 2MSL wait state). For applications using a well known socket
address or port it may not be possible to bind a socket to the required
SocketAddress if there is a connection in the timeout state involving the socket
address or port.
Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress)
allows the socket to be bound even though a previous connection is in a timeout state.
What exactly does SO_REUSEADDR do?
This socket option tells the kernel that even if this port is busy (in the TIME_WAIT state), go ahead and reuse it anyway. If it is busy, but with another state, you will still get an address already in use error. It is useful if your server has been shut down, and then restarted right away while sockets are still active on its port. You should be aware that if any unexpected data comes in, it may confuse your server, but while this is possible, it is not likely.
|
|
|
|
|
|
|
|