Logo Search packages:      
Sourcecode: zeroc-ice-java version File versions  Download package

Network.java

// **********************************************************************
//
// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************

package IceInternal;

public final class Network
{
    public static boolean
    connectionLost(java.io.IOException ex)
    {
        //
        // TODO: The JDK raises a generic IOException for certain
        // cases of connection loss. Unfortunately, our only choice is
        // to search the exception message for distinguishing phrases.
        //

        String msg = ex.getMessage().toLowerCase();

        if(msg != null)
        {
            final String[] msgs =
            {
                "connection reset by peer", // ECONNRESET
                "cannot send after socket shutdown", // ESHUTDOWN (Win32)
                "cannot send after transport endpoint shutdown", // ESHUTDOWN (Linux)
                "software caused connection abort", // ECONNABORTED
                "an existing connection was forcibly closed", // unknown
              "connection closed by remote host", // unknown
              "an established connection was aborted by the software in your host machine", // unknown (Win32)
              "broken pipe", // EPIPE
            "there is no process to read data written to a pipe", // EPIPE? (AIX JDK 1.4.2)
            "socket is closed" // unknown (AIX JDK 1.4.2)
            };

            for(int i = 0; i < msgs.length; i++)
            {
                if(msg.indexOf(msgs[i]) != -1)
                {
                    return true;
                }
            }
        }

        return false;
    }

    public static boolean
    connectionRefused(java.net.ConnectException ex)
    {
        //
        // The JDK raises a generic ConnectException when the server
        // actively refuses a connection. Unfortunately, our only
        // choice is to search the exception message for
        // distinguishing phrases.
        //

        String msg = ex.getMessage().toLowerCase();

        if(msg != null)
        {
            final String[] msgs =
            {
                "connection refused", // ECONNREFUSED
            "remote host refused an attempted connect operation" // ECONNREFUSED (AIX JDK 1.4.2)
            };

            for(int i = 0; i < msgs.length; i++)
            {
                if(msg.indexOf(msgs[i]) != -1)
                {
                    return true;
                }
            }
        }

        return false;
    }

    public static boolean
    notConnected(java.net.SocketException ex)
    {
      String msg = ex.getMessage().toLowerCase();
      if(msg.indexOf("transport endpoint is not connected") != -1)
      {
          return true;
      }
      //
      // BUGFIX: We check for EINVAL because shutdown() under Mac OS
      // X returns EINVAL if the server side is gone.
      //
      else if(msg.indexOf("invalid argument") != -1)
      {
          return true;
      }
      return false;
    }

    public static java.nio.channels.SocketChannel
    createTcpSocket()
    {
        try
        {
            java.nio.channels.SocketChannel fd = java.nio.channels.SocketChannel.open();
            java.net.Socket socket = fd.socket();
            socket.setTcpNoDelay(true);
            socket.setKeepAlive(true);
            return fd;
        }
        catch(java.io.IOException ex)
        {
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static java.nio.channels.ServerSocketChannel
    createTcpServerSocket()
    {
        try
        {
            java.nio.channels.ServerSocketChannel fd = java.nio.channels.ServerSocketChannel.open();
            //
            // It's not possible to set TCP_NODELAY or KEEP_ALIVE
            // on a server socket in Java
            //
            //java.net.Socket socket = fd.socket();
            //socket.setTcpNoDelay(true);
            //socket.setKeepAlive(true);
            return fd;
        }
        catch(java.io.IOException ex)
        {
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static java.nio.channels.DatagramChannel
    createUdpSocket()
    {
        try
        {
            return java.nio.channels.DatagramChannel.open();
        }
        catch(java.io.IOException ex)
        {
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    private static void
    closeSocketNoThrow(java.nio.channels.SelectableChannel fd)
    {
        try
      {
          fd.close();
      }
      catch(java.io.IOException ex)
      {
          // Ignore
      }
    }

    public static void
    closeSocket(java.nio.channels.SelectableChannel fd)
    {
      try
      {
          fd.close();
      }
      catch(java.io.IOException ex)
      {
          Ice.SocketException se = new Ice.SocketException();
          se.initCause(ex);
          throw se;
      }
    }

    public static void
    setBlock(java.nio.channels.SelectableChannel fd, boolean block)
    {
        try
        {
            fd.configureBlocking(block);
        }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static java.net.InetSocketAddress
    doBind(java.nio.channels.ServerSocketChannel fd, java.net.InetSocketAddress addr)
    {
        try
        {
            java.net.ServerSocket sock = fd.socket();
            sock.bind(addr);
            return (java.net.InetSocketAddress)sock.getLocalSocketAddress();
        }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static java.net.InetSocketAddress
    doBind(java.nio.channels.DatagramChannel fd, java.net.InetSocketAddress addr)
    {
        try
        {
            java.net.DatagramSocket sock = fd.socket();
            sock.bind(addr);
            return (java.net.InetSocketAddress)sock.getLocalSocketAddress();
        }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static void
    doConnect(java.nio.channels.SocketChannel fd, java.net.InetSocketAddress addr, int timeout)
    {
        try
        {
            if(!fd.connect(addr))
            {
                int delay;
                if(timeout > 0 && timeout < 100)
                {
                    delay = timeout;
                }
                else
                {
                    delay = 100; // 100 ms
                }

                int timer = 0;
                while(!fd.finishConnect())
                {
                    if(timeout > 0 && timer >= timeout)
                    {
                        closeSocketNoThrow(fd);
                        throw new Ice.ConnectTimeoutException();
                    }
                    try
                    {
                        Thread.sleep(delay);
                        timer += delay;
                    }
                    catch(InterruptedException ex)
                    {
                    }
                }
            }
        }
        catch(java.net.ConnectException ex)
        {
          closeSocketNoThrow(fd);

            Ice.ConnectFailedException se;
          if(connectionRefused(ex))
          {
            se = new Ice.ConnectionRefusedException();
          }
          else
          {
            se = new Ice.ConnectFailedException();
          }
            se.initCause(ex);
            throw se;
        }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static void
    doConnect(java.nio.channels.DatagramChannel fd, java.net.InetSocketAddress addr, int timeout)
    {
        try
        {
            fd.connect(addr);
        }
        catch(java.net.ConnectException ex)
        {
          closeSocketNoThrow(fd);

            Ice.ConnectFailedException se;
          if(connectionRefused(ex))
          {
            se = new Ice.ConnectionRefusedException();
          }
          else
          {
            se = new Ice.ConnectFailedException();
          }
            se.initCause(ex);
            throw se;
        }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static java.nio.channels.SocketChannel
    doAccept(java.nio.channels.ServerSocketChannel fd, int timeout)
    {
        java.nio.channels.SocketChannel result = null;
        while(result == null)
        {
            try
            {
                result = fd.accept();
                if(result == null)
                {
                    java.nio.channels.Selector selector = java.nio.channels.Selector.open();

                    try
                    {
                        while(true)
                        {
                            try
                            {
                                java.nio.channels.SelectionKey key =
                                    fd.register(selector, java.nio.channels.SelectionKey.OP_ACCEPT);
                                int n;
                                if(timeout > 0)
                                {
                                    n = selector.select(timeout);
                                }
                                else if(timeout == 0)
                                {
                                    n = selector.selectNow();
                                }
                                else
                                {
                                    n = selector.select();
                                }

                                if(n == 0)
                                {
                                    throw new Ice.TimeoutException();
                                }

                                break;
                            }
                            catch(java.io.IOException ex)
                            {
                        if(interrupted(ex))
                        {
                            continue;
                        }
                                Ice.SocketException se = new Ice.SocketException();
                                se.initCause(ex);
                                throw se;
                            }
                        }
                    }
                    finally
                    {
                        try
                        {
                            selector.close();
                        }
                        catch(java.io.IOException ex)
                        {
                            // Ignore
                        }
                    }
                }
            }
            catch(java.io.IOException ex)
            {
            if(interrupted(ex))
            {
                continue;
            }
                Ice.SocketException se = new Ice.SocketException();
                se.initCause(ex);
                throw se;
            }
        }

        try
        {
            java.net.Socket socket = result.socket();
            socket.setTcpNoDelay(true);
            socket.setKeepAlive(true);
        }
        catch(java.io.IOException ex)
        {
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }

        return result;
    }

    public static void
    setSendBufferSize(java.nio.channels.DatagramChannel fd, int size)
    {
      try
      {
          java.net.DatagramSocket socket = fd.socket();
          socket.setSendBufferSize(size);
      }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static int
    getSendBufferSize(java.nio.channels.DatagramChannel fd)
    {
      int size;
      try
      {
          java.net.DatagramSocket socket = fd.socket();
          size = socket.getSendBufferSize();
      }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
      return size;
    }

    public static void
    setRecvBufferSize(java.nio.channels.ServerSocketChannel fd, int size)
    {
      try
      {
          java.net.ServerSocket socket = fd.socket();
          socket.setReceiveBufferSize(size);
      }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static void
    setRecvBufferSize(java.nio.channels.DatagramChannel fd, int size)
    {
      try
      {
          java.net.DatagramSocket socket = fd.socket();
          socket.setReceiveBufferSize(size);
      }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
    }

    public static int
    getRecvBufferSize(java.nio.channels.ServerSocketChannel fd)
    {
        int size;
      try
      {
          java.net.ServerSocket socket = fd.socket();
          size = socket.getReceiveBufferSize();
      }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
      return size;
    }

    public static int
    getRecvBufferSize(java.nio.channels.DatagramChannel fd)
    {
        int size;
      try
      {
          java.net.DatagramSocket socket = fd.socket();
          size = socket.getReceiveBufferSize();
      }
        catch(java.io.IOException ex)
        {
          closeSocketNoThrow(fd);
            Ice.SocketException se = new Ice.SocketException();
            se.initCause(ex);
            throw se;
        }
      return size;
    }

    public static java.net.InetSocketAddress
    getAddress(String host, int port)
    {
        try
        {
            java.net.InetAddress addr = java.net.InetAddress.getByName(host);
            return new java.net.InetSocketAddress(addr, port);
        }
        catch(java.net.UnknownHostException ex)
        {
          Ice.DNSException e = new Ice.DNSException();
          e.host = host;
          throw e;
        }
    }

    public static java.net.InetAddress
    getLocalAddress()
    {
        java.net.InetAddress addr = null;

        try
        {
            addr = java.net.InetAddress.getLocalHost();
        }
        catch(java.net.UnknownHostException ex)
        {
            //
            // May be raised on DHCP systems.
            //
        }
        catch(NullPointerException ex)
        {
            //
            // Workaround for bug in JDK.
            //
        }

        if(addr == null)
        {
            //
            // Iterate over the network interfaces and pick an IP
            // address (preferably not the loopback address).
            //
            java.net.InetAddress loopback = null;
          java.util.ArrayList addrs = getLocalAddresses();
            java.util.Iterator iter = addrs.iterator();
            while(addr == null && iter.hasNext())
            {
            java.net.InetAddress a = (java.net.InetAddress)iter.next();
                if(!a.isLoopbackAddress())
                {
                    addr = a;
                }
                else
                {
                    loopback = a;
                }
            }

            if(addr == null)
            {
                addr = loopback; // Use the loopback address as the last resort.
            }
        }

        assert(addr != null);
        return addr;
    }

    public static java.util.ArrayList
    getLocalHosts()
    {
        java.util.ArrayList hosts = new java.util.ArrayList();
        java.util.ArrayList addrs = getLocalAddresses();
      java.util.Iterator iter = addrs.iterator();
      while(iter.hasNext())
      {
          hosts.add(((java.net.InetAddress)iter.next()).getHostAddress());
      }
      return hosts;
    }

    public static java.util.ArrayList
    getLocalAddresses()
    {
        java.util.ArrayList result = new java.util.ArrayList();

      try
      {
          java.util.Enumeration ifaces = java.net.NetworkInterface.getNetworkInterfaces();
          while(ifaces.hasMoreElements())
          {
                java.net.NetworkInterface iface = (java.net.NetworkInterface)ifaces.nextElement();
                java.util.Enumeration addrs = iface.getInetAddresses();
            while(addrs.hasMoreElements())
            {
                java.net.InetAddress addr = (java.net.InetAddress)addrs.nextElement();
                if(!(addr instanceof java.net.Inet6Address))
                {
                      result.add(addr);
                }
            }
          }
      }
      catch(java.net.SocketException e)
      {
          Ice.SocketException se = new Ice.SocketException();
          se.initCause(e);
          throw se;
      }

      return result;
    }

    public static final class SocketPair
    {
        public java.nio.channels.spi.AbstractSelectableChannel source;
        public java.nio.channels.WritableByteChannel sink;
    }

    public static SocketPair
    createPipe()
    {
        SocketPair fds = new SocketPair();

      //
      // BUGFIX: This method should really be very simple.
      // Unfortunately, using a pipe causes a kernel crash under
      // MacOS 10.3.9.
      //
      //try
      //{
      //   java.nio.channels.Pipe pipe = java.nio.channels.Pipe.open();
      //   fds.sink = pipe.sink();
      //   fds.source = pipe.source();
      //}
        //catch(java.io.IOException ex)
      //{
      //   Ice.SocketException se = new Ice.SocketException();
      //   se.initCause(ex);
      //   throw se;
      //}
      //
      
        java.nio.channels.ServerSocketChannel fd = createTcpServerSocket();
      
      java.net.InetSocketAddress addr = new java.net.InetSocketAddress("127.0.0.1", 0);
      
      addr = doBind(fd, addr);
      
        try
      {
            java.nio.channels.SocketChannel sink = createTcpSocket();
          fds.sink = sink;
          doConnect(sink, addr, -1);
            try
          {
            fds.source = doAccept(fd, -1);
          }
          catch(Ice.LocalException ex)
            {
            try
            {
                    fds.sink.close();
            }
            catch(java.io.IOException e)
            {
                }
            throw ex;
          }
        }
      finally
      {
          closeSocketNoThrow(fd);
      }
      
      return fds;
    }
    
    public static String
    fdToString(java.nio.channels.SelectableChannel fd)
    {
      if(fd == null)
      {
          return "<closed>";
      }

      java.net.InetAddress localAddr = null, remoteAddr = null;
      int localPort = -1, remotePort = -1;

      if(fd instanceof java.nio.channels.SocketChannel)
      {
          java.net.Socket socket = ((java.nio.channels.SocketChannel)fd).socket();
          localAddr = socket.getLocalAddress();
          localPort = socket.getLocalPort();
          remoteAddr = socket.getInetAddress();
          remotePort = socket.getPort();
      }
      else if(fd instanceof java.nio.channels.DatagramChannel)
      {
          java.net.DatagramSocket socket = ((java.nio.channels.DatagramChannel)fd).socket();
          localAddr = socket.getLocalAddress();
          localPort = socket.getLocalPort();
          remoteAddr = socket.getInetAddress();
          remotePort = socket.getPort();
      }
      else
      {
          assert(false);
      }

      return addressesToString(localAddr, localPort, remoteAddr, remotePort);
    }

    public static String
    fdToString(java.net.Socket fd)
    {
      if(fd == null)
      {
          return "<closed>";
      }

      java.net.InetAddress localAddr = fd.getLocalAddress();
      int localPort = fd.getLocalPort();
      java.net.InetAddress remoteAddr = fd.getInetAddress();
      int remotePort = fd.getPort();

      return addressesToString(localAddr, localPort, remoteAddr, remotePort);
    }

    public static String
    addressesToString(java.net.InetAddress localAddr, int localPort, java.net.InetAddress remoteAddr, int remotePort)
    {
      StringBuffer s = new StringBuffer();
      s.append("local address = ");
      s.append(localAddr.getHostAddress());
      s.append(':');
      s.append(localPort);
      if(remoteAddr == null)
      {
          s.append("\nremote address = <not connected>");
      }
      else
      {
          s.append("\nremote address = ");
          s.append(remoteAddr.getHostAddress());
          s.append(':');
          s.append(remotePort);
      }

      return s.toString();
    }

    public static String
    addrToString(java.net.InetSocketAddress addr)
    {
        StringBuffer s = new StringBuffer();
        s.append(addr.getAddress().getHostAddress());
        s.append(':');
        s.append(addr.getPort());
        return s.toString();
    }

    public static boolean
    interrupted(java.io.IOException ex)
    {
      return ex instanceof java.io.InterruptedIOException ||
          ex.getMessage().indexOf("Interrupted system call") >= 0 ||
          ex.getMessage().indexOf("A system call received an interrupt") >= 0; // AIX JDK 1.4.2
    }
}

Generated by  Doxygen 1.6.0   Back to index