go to  ForumEasy.com   
JavaPro  
 
 
   Home  |  MyForum  |  FAQ  |  Archive    You are not logged in. [Login] or [Register]  
Forum Home » Java I/O » "Address already in use" errors
Email To Friend  |   Set Alert To This Topic Rewarding Points Availabe: 0 (What's this) New Topic  |   Post Reply
Author Topic: "Address already in use" errors
EricJ
member
offline   
 
posts: 50
joined: 02/22/2007
from: CA
  posted on: 04/12/2007 09:29:53 PM    Edit  |   Quote  |   Report 
"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)

 Profile | Reply Points Earned: 0
EricJ
member
offline   
 
posts: 50
joined: 02/22/2007
from: CA
  posted on: 04/12/2007 09:35:48 PM    Edit  |   Quote  |   Report 
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.

 Profile | Reply Points Earned: 0
EricJ
member
offline   
 
posts: 50
joined: 02/22/2007
from: CA
  posted on: 04/12/2007 09:37:52 PM    Edit  |   Quote  |   Report 
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

  •  Profile | Reply Points Earned: 0
    EricJ
    member
    offline   
     
    posts: 50
    joined: 02/22/2007
    from: CA
      posted on: 02/23/2010 09:12:16 PM    Edit  |   Quote  |   Report 
    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.


     Profile | Reply Points Earned: 0

     
    Powered by ForumEasy © 2003-2005, All Rights Reserved. | Privacy Policy | Terms of Use
     
    Get your own forum today. It's easy and free.