[Webfunds-commits] java/webfunds/comms BasicCommsManager.java BasicRequestor.java SocketSupport.java

Ian Grigg iang@cypherpunks.ai
Wed, 4 Apr 2001 10:19:53 -0400 (AST)


iang        01/04/04 10:19:53

  Added:       webfunds/comms BasicCommsManager.java BasicRequestor.java
                        SocketSupport.java
  Log:
  implementations of new Comms interfaces -- how to get to the net

Revision  Changes    Path
1.1                  java/webfunds/comms/BasicCommsManager.java

Index: BasicCommsManager.java
===================================================================
/*
 * Copyright (c) 2001 Systemics Inc on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */
package webfunds.comms;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;
import java.net.URL;
import java.net.Socket;
import java.net.SocketException;

/**
 * A CommsManager that can return BasicRequestors.
 *
 * @version $Id: BasicCommsManager.java,v 1.1 2001/04/04 14:19:53 iang Exp $
 */
public class BasicCommsManager
    implements CommsManager
{

    /**
     * Create a new BasicCommsManager object.
     *
     */
    public BasicCommsManager()
    {
    }

    /**
     * Create a new Requestor object.
     *
     * @param host is the domain name or IP number for the remote node
     * @param port is the port to connect to
     * @param url the http location where requests are sent
     */
    public SingleRequestor getSingleRequestor(URL url)
    {
        if (url == null)
            throw new IllegalArgumentException("url null");
        return getSingleRequestor(url.getHost(), url.getPort());
    }

    /**
     * Create a new Requestor object.
     *
     * @param host is the domain name or IP number for the remote node
     * @param port is the port to connect to
     * @param url the http location where requests are sent
     */
    public SingleRequestor getSingleRequestor(String host, int port)
    {
        SocketSupport.checkParams(host, port);

        BasicRequestor req = new BasicRequestor(host, port);
        return req;
    }
}



1.1                  java/webfunds/comms/BasicRequestor.java

Index: BasicRequestor.java
===================================================================
/*
 * Copyright (c) 2001 Systemics Inc on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */
package webfunds.comms;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;
import java.net.URL;
import java.net.Socket;
import java.net.SocketException;

/**
 * Provides SingleRequestor that can pass a single request to a server.
 *
 * @version $Id: BasicRequestor.java,v 1.1 2001/04/04 14:19:53 iang Exp $
 */
public class BasicRequestor
    implements SingleRequestor
{

    /**
     * The location of the remote.
     */
    protected String host;
    protected int    port;

    /**
     * Create a new Requestor object.
     *
     * @param url the http location where requests are sent
     */
    public BasicRequestor(URL url)
    {
        this.host = url.getHost();
        this.port = url.getPort();
    }

    /**
     * Create a new Requestor object.
     *
     * @param host is the domain name or IP number for the remote node
     * @param port is the port to connect to
     */
    public BasicRequestor(String host, int port)
    {
        this.host = host;
        this.port = port;
    }



    public int max  = SocketSupport.MAX;
    /** Set the maximum number of characters to be returned.  */
    public void setMax(int max)               { this.max = max; }
    public int  getMax()                      { return max; }

    public String   getHost()                 { return host; }
    public int      getPort()                 { return port; }

    private boolean used = false;
    public boolean  isUsed()                  { return used; }



    /**
     *  Send the packet to host/port, and
     *  return the single packet that returns.
     *  Only getMax() bytes or less will be returned.
     */
    public byte[] get(byte[] packet)
        throws RawException
    {
        if (used)
            throw new RawUsedException("already used");
        used = true;

        byte[] buf = SocketSupport.get(host, port, packet, max);
        return buf;
    }

}



1.1                  java/webfunds/comms/SocketSupport.java

Index: SocketSupport.java
===================================================================
/*
 * Copyright (c) 2001 Systemics Inc on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */
package webfunds.comms;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;
import java.net.URL;
import java.net.Socket;
import java.net.SocketException;

import webfunds.util.Panic;

/**
 * Do some basic Socket things.
 *
 * @version $Id: SocketSupport.java,v 1.1 2001/04/04 14:19:53 iang Exp $
 */
public class SocketSupport
{
    private SocketSupport() {}

    public static final int MAX = 45 * 1024;


    /**
     * Check out these params for basic sanity.
     *
     * @param host is the domain to open to
     * @param port is the port, 80 if <= 0
     *
     * @except IllegalArgumentException if any param is no good
     */
    public static void checkParams(String host, int port)
    {
        if (host == null)
            throw new IllegalArgumentException("host null");
        if (host.length() <= 0)
            throw new IllegalArgumentException("host empty");

        if ( ! (0 < port && port < 65536) )
            throw new IllegalArgumentException("bad port number: " + port);
    }
            
            
         
    /**        
     * Send a request to a socket and read the reply from a socket.
     *
     * @param host is the domain to open to
     * @param port is the port
     * @param request the bytes to write to opened socket
     * @param size is the maximum number of chars
     * @return the bytes read
     *
     * @except RawURLException connect details bad, check them
     * @except RawConnectException connection refused (try again later)
     */
    public static byte[] get(String host, int port,
                                   byte[] request, int max)
        throws RawURLException, RawConnectException
    {
        Socket sock = SocketSupport.getSocket(host, port);

        byte[] buf = SocketSupport.getOnce(sock, request, max);

        return buf;
    }

    /**
     * Send a request and read the reply from a socket.
     *
     * @param host is the domain to open to
     * @param request the bytes to write to opened socket
     * @param port is the port, 80 if <= 0
     * @param size is the port, some default if <= 0
     * @return the bytes read
     *
     * @except RawURLException connect details bad, check them
     * @except RawConnectException connection refused (try again later)
     */
    public static Socket getSocket(String host, int port)
        throws RawURLException, RawConnectException
    {

        checkParams(host, port);
     
        Socket sock;
        try {
            sock = new Socket(host, port);
        } catch (java.net.UnknownHostException ex) {
            throw new RawURLException("host: " + host + ":" + port +
                                           "\n" + ex);
        } catch (java.net.ConnectException ex) {  // from IOEx
            throw new RawConnectException("down: " + host + ":" + port);
        } catch (java.net.NoRouteToHostException ex) {  // from IOEx
            throw new RawConnectException("no route: "+host+":"+port);
        } catch (IOException ex) {
            //
            // Damn.
            // Macs throw IOException instead of something more specific.
            // java.io.IOException: OpenTransport error -3155; connect failed1
            // Checking on meaning...
            //
            ex.printStackTrace();
            throw new RawURLException("(MAC) URL bad ?: "+host+":"+port);
        }
                 
        //  
        //  This is most unsatisfactory.
        //  Can't set the timeout on the connect!
        //  Hmm, this is a socket problem, not a Java problem.
        //
        //  Note that this sets the timeout for each read, not them all.
        //
        try {
            sock.setSoTimeout(30 * 1000);  
            sock.setTcpNoDelay(true);
        } catch (SocketException ex) {
            ex.printStackTrace();
            throw new Panic("setSocket: " + ex);
        }

        return sock;
    }

    /**
     *  Send a request and read the reply from a socket.
     *  On return, the streams and the socket are closed.
     *
     *  @param socket is the socket to read and write from
     *  @param request the bytes to write to opened socket
     *  @param size is the maximum number of characters to read
     *  @return the bytes read, the array is never greater than size, nor null
     *
     *  @except RawURLException connect details bad, check them
     *  @except RawConnectException connection refused (try again later)
     */
    public static byte[] getOnce(Socket sock,
                                   byte[] request, int size)   
        throws RawURLException, RawConnectException
    {
     
        OutputStream os;
        InputStream is;
        try {
            os = sock.getOutputStream();
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new RawConnectException("host bad (getOut IOEx): " + ex);
        }

        try {
            is = sock.getInputStream();
        } catch (NullPointerException ex) {
            // blech.  if the conn goes before open, socket blows up
            throw new RawConnectException("dropped con (NPE): " + ex);
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new RawConnectException("host bad (getIn IOEx): " + ex);
        }

        try {
            os.write(request);
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new RawConnectException("host bad (write IOEx): " + ex);
        }


        byte[] buf = new byte[size];

        int i = 0;
        int offset = 0;
        while (i >= 0 && (offset < size))
        {
            offset += i;
            try {
                i = is.read(buf, offset, size - offset);
            } catch (IOException ex) {
                // ex.printStackTrace();
                throw new RawConnectException("sock bad (read IOEx): "+ex);
            }
        }

        try
        {
            is.close();
            sock.close();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
            throw new RawConnectException("close (IOEx): "+ex);
        }

        byte[] b2 = new byte[offset];
        for (i = 0; i < offset; i++)
            b2[i] = buf[i];

        return b2;
    }

}