java/ch/wlkl/javaExamples/ExNet.java

/*
 * ExNet.java
 *
 * Created on 24. Dezember 2003, 13:51
 */

/**
 * 
 * @author walter
 */
package ch.wlkl.javaExamples;

import java.net.*;
import java.io.IOException;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.*;

public class ExNet {

    void hostname(String nam) {
        try {
            InetAddress adr = InetAddress.getByName(nam);
            System.out.println("hostname " + nam + " => " + adr);
        } catch (Throwable ex) {
            System.out.println("hostname " + nam + " ex " + ex);
        }
    }

    WritableByteChannel out = Channels.newChannel(System.out);

    ReadableByteChannel in = Channels.newChannel(System.in);

    class Echo extends Thread {
        String m;

        SocketChannel sc;

        Charset charset = Charset.forName("ISO-8859-1");

        ByteBuffer buf = ByteBuffer.allocateDirect(1000);

        Echo() {
        }

        Echo(String m, SocketChannel sc) {
            this.m = m;
            this.sc = sc;
        }

        String echo1(ReadableByteChannel fr, String m, WritableByteChannel to) {
            buf.clear();
            try {
                int nr = fr.read(buf);
                if (nr <= 0)
                    return (nr == 0 ? "0: " : "err: ") + nr
                            + " returned from read";
            } catch (Throwable ex) {
                return "err: read " + m + ": " + ex;
            }
            buf.flip();
            ByteBuffer hb = charset.encode(m);
            ByteBuffer ob = ByteBuffer.allocateDirect(hb.limit() + buf.limit());
            ob.put(hb);
            ob.put(buf);
            ob.flip();
            while (ob.hasRemaining()) {
                try {
                    to.write(ob);
                } catch (Throwable ex) {
                    return "err: write " + m + ": " + ex;
                }
            }
            buf.flip();
            return charset.decode(buf).toString();
        }

        public void run() {
            System.out.println(m + "accepted: " + sc);
            for (String res = ""; !res.startsWith("err:");) {
                res = echo1(sc, m, sc);
                System.out.println(m + "echoed: " + res);
            }

        }
    }

    void echo() {
        Echo ec = new Echo();
        for (String res = "";;) {
            res = ec.echo1(in, "echo >>>", out);
            System.out.println("echo1 returns (end for end): " + res);
            if (res.startsWith("end"))
                break;
        }
        System.out.println("echo returning.........");
    }

    void client(String name, int port) {
        Echo ec = new Echo("client " + name + ":" + port + " ", null);
        try {
            ec.sc = SocketChannel.open(new InetSocketAddress(name, port));
            ec.sc.configureBlocking(false);
            System.out.println(ec.m + "open: " + ec.sc);
            for (String res = "";;) {
                res = ec.echo1(ec.sc, ec.m + "receive: ", out);
                System.out.print(ec.m + "echo recd: " + res);
                if (res.startsWith("err:"))
                    break;
                res = ec.echo1(in, ec.m + "send: ", ec.sc);
                System.out.print(ec.m + "echo sent: " + res);
                if (res.startsWith("end") || res.startsWith("err:"))
                    break;
                Thread.sleep(200);
            }
        } catch (Throwable ex) {
            System.out.println(ec.m + " client exception: " + ex);
        }
    }

    void server1(int port) {
        String m = "server1:" + port + " ";
        try {
            ServerSocketChannel sr = ServerSocketChannel.open();
            sr.socket().bind(new InetSocketAddress(port));
            for (int i = 0; i < 3; i++) {
                System.out.println(m + "waiting for " + i + " (of 3) connects "
                        + sr);
                new Echo(m + "/" + i + " ", sr.accept()).start(); // start:
                                                                  // multithreads,
                                                                  // run()
                                                                  // single
            }
        } catch (Throwable ex) {
            System.out.println(m + "ex " + ex);
        }
    }

    void serverMux(int port) {
        String m = "serverMux :" + port + " ";
        try {
            ServerSocketChannel sr = ServerSocketChannel.open();
            sr.socket().bind(new InetSocketAddress(port));
            sr.configureBlocking(false);
            ArrayList lst = new ArrayList();
            lst.add(sr);
            for (int mlx = 0; lst.size() > 0; mlx++) {
                int doX = 0;
                System.out.println(m + "mainloop start " + mlx + " list "
                        + lst.size());
                for (int lx = 0; lx < lst.size(); lx++) {
                    Object obj = lst.get(lx);
                    if (sr.getClass().isInstance(obj)) {
                        SocketChannel sc = ((ServerSocketChannel) obj).accept();
                        if (sc == null)
                            continue;
                        sc.configureBlocking(false);
                        lst.add(sc);
                        doX++;
                        System.out.println(m + "accepted/" + (lst.size() - 1)
                                + " " + sc);
                    } else if (SocketChannel.class.isInstance(obj)) {
                        Echo ec = new Echo(m + "/" + lx + ": ",
                                (SocketChannel) obj);
                        String res = ec.echo1(ec.sc, ec.m, ec.sc);
                        if (res.startsWith("0:"))
                            continue;
                        System.out.println(ec.m + "echo1 returns: " + res);
                        doX++;
                        if (!res.startsWith("err:"))
                            continue;
                        System.out.println(ec.m + ec.sc + " isConnected "
                                + ec.sc.isConnected() + ", isOpen "
                                + ec.sc.isOpen() + ", validOps "
                                + ec.sc.validOps() + ", socket isConnected "
                                + ec.sc.socket().isConnected() + ", isClosed "
                                + ec.sc.socket().isClosed()
                                + ", isInputShutdown "
                                + ec.sc.socket().isInputShutdown()
                                + ", isOutputShutdown "
                                + ec.sc.socket().isOutputShutdown());
                        System.out.println(ec.m
                                + "cannot detect close ... assume it is!");
                        lst.remove(obj);
                        ec.sc.close();
                    } else {
                        System.out.println(m + "list contains bad class "
                                + obj.getClass() + " of " + obj);
                    }
                }
                if (doX <= 0) {
                    System.out.println(m + "sleeping after empty loop");
                    Thread.sleep(3000);
                }
            }
        } catch (Throwable ex) {
            System.out.println(m + "ex " + ex);
        }
    }

    void serverSel(int port) {
        String m = "serverSel :" + port + " ";
        try {
            ServerSocketChannel sr = ServerSocketChannel.open();
            sr.socket().bind(new InetSocketAddress(port));
            sr.configureBlocking(false);
            Selector sel = Selector.open();
            sr.register(sel, SelectionKey.OP_ACCEPT);
            int cnt = 0;
            int accX = 0;
            int selX;
            while ((selX = sel.select()) > 0) {
                System.out.println(m + "loop " + ++cnt + "selX " + selX);
                for (Iterator it = sel.selectedKeys().iterator(); it.hasNext();) {
                    SelectionKey key = (SelectionKey) it.next();
                    it.remove();
                    if (key.isAcceptable()) {
                        SocketChannel sc = ((ServerSocketChannel) key.channel())
                                .accept();
                        sc.configureBlocking(false);
                        Echo ec = new Echo(m + "acc" + ++accX + ": ", sc);
                        sc.register(sel, SelectionKey.OP_READ, ec);
                        System.out.println(m + "accepted: " + ec.m + sc);
                    } else if (key.isReadable()) {
                        Echo ec = (Echo) key.attachment();
                        String res = ec.echo1(ec.sc, ec.m, ec.sc);
                        if (res.startsWith("0:"))
                            continue;
                        System.out.println(ec.m + "echo1 returns: " + res);
                        if (!res.startsWith("err:"))
                            continue;
                        System.out.println(ec.m + ec.sc + " isConnected "
                                + ec.sc.isConnected() + ", isOpen "
                                + ec.sc.isOpen() + ", validOps "
                                + ec.sc.validOps() + ", socket isConnected "
                                + ec.sc.socket().isConnected() + ", isClosed "
                                + ec.sc.socket().isClosed()
                                + ", isInputShutdown "
                                + ec.sc.socket().isInputShutdown()
                                + ", isOutputShutdown "
                                + ec.sc.socket().isOutputShutdown());
                        System.out.println(ec.m + "closing!");
                        ec.sc.close();
                    } else {
                        System.out.println(m + "bad key returned "
                                + key.getClass() + " of " + key);
                    }
                }
            }
        } catch (IOException ex) {
            System.out.println(m + "ex " + ex);
        }
    }

    public static void main(String[] args) {
        // new Java(new String [0], new String [] {"hostname", "walter",
        // "hostname", "localhost",
        //    "hostname", "google.ch", "hostname", "google.ch", "hostname",
        // "www.google.ch"}).invokeMethods(new ExNet());
        new Java(args, new String[] { "serverSel", "888" })
                .invokeMethods(new ExNet());
    }
}