WebServer using SocketServer, ServerSocketChannel and AsynchronousServerSocketChannel

Joe

Thành viên VIP
21/1/13
2,736
1,256
113
Hi,
as I showed you how to access the web with Socket/SocketChannel/AsynchrousSocketChannel I show you today how to build a Web-based Client/Server using the classic Socket/ServerSocket and the new technology NIO with Channel: ServerSocketChannel and AsynchronousServerSocketChannel
To make the matters more transparent I design a Webserver that has 3 internal servers using 3 different technologies:
- Socket/ServerSocket with port 6786,
- SocketChannel/ServerSocketChannel with port 6787,
- AsynchronousSocketChannel/AsynchronousServerSocketChannel with port 6789
Each internal server is capable to spawn n serving threads (SocBean, NIOBean and AsynBean). The codes are straightforward using Swing (see screenshot). OmniServer allows clients to download a particular file from the server using
a) Socket technology
b) NIO Channel technology
The timestamp shows you relatively how different the accessing processes are.
PHP:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.nio.*;
import java.awt.event.*;
import java.nio.channels.*;
//
import javax.swing.*;
// Joe - Congdongjava.com/forum
public class OmniServer extends JFrame implements ActionListener {
      
        private ServerSocket socSvr;
        private ServerSocketChannel nioSvr;
        private AsynchronousServerSocketChannel asynSvr;
        // Classic SocketServer
        public class SocServer extends Thread {
            public SocServer(int port) {
                        this.port = port;
                }
                private int port;
        public void run( ) {
          try {
            socSvr = new ServerSocket(port);
            while (true)  (new SocBean(socSvr.accept())).start();
          } catch (Exception e) {  }      
        }
        }
        // classic Downloading Socket Thread
        private class SocBean extends Thread {
                public SocBean(Socket soc) {
                        this.soc = soc;
                }
                private Socket soc;
                public void run() {
                        try {
                                long be = System.currentTimeMillis();
                                InputStream inp = soc.getInputStream();
                                OutputStream out = soc.getOutputStream();
                                byte[] bb = new byte[4096];
                                int le = inp.read(bb); // get the fileName
                                String fn = new String(bb, 0, le);
                                FileInputStream fi = new FileInputStream(fn);
                                while ((le = fi.read(bb)) > 0) out.write(bb, 0, le);
                                fi.close();
                                out.flush();
                                inp.close();
                                soc.close();
                                be = System.currentTimeMillis() - be;
                                synchronized (jta) {
                                        jta.append("SocServer\nTransferred Time ="+be+
                                                   " mSec. for the File:"+fn+"\n");
                                        jta.setCaretPosition(jta.getText().length());
                                }
                        } catch (Exception e) {
                                synchronized (jta) {
                                        jta.append("SocServerError:\n"+e.toString()+"\n");
                                        jta.setCaretPosition(jta.getText().length());
                                }
                        }
                }
        }
        // NIO ServerSocketChannel
        public class NIOServer extends Thread {
            public NIOServer(int port) {
                        this.port = port;
                }
                private int port;
        public void run( ) {
          try {
            nioSvr = ServerSocketChannel.open();
            nioSvr.socket().bind(new InetSocketAddress(port));
            //nSvr.configureBlocking(false);
            while (true) (new NIOBean(nioSvr.accept())).start();
          } catch (Exception e) {  }
        }
        }
        // NIO Downloading SocketChannel Thread
        private class NIOBean extends Thread {
                public NIOBean(SocketChannel soc) {
                        this.soc = soc;
                }
                private SocketChannel soc;
                public void run() {
                        try {
                                long be = System.currentTimeMillis();
                                ByteBuffer wbuf = ByteBuffer.allocateDirect(4096);
                                int le = soc.read(wbuf); // get the fileName
                                wbuf.flip();
                                byte[] bb = new byte[4096];
                                wbuf.get(bb, 0, le);
                                String fn = new String(bb, 0, le);
                                FileInputStream fi = new FileInputStream(fn);
                                while ((le = fi.read(bb)) > 0) soc.write(ByteBuffer.wrap(bb, 0, le));
                                fi.close();
                                soc.close();
                                be = System.currentTimeMillis() - be;
                                synchronized (jta) {
                                        jta.append("SocChannelServer\nTransferred Time ="+be+
                                                   " mSec. for the File:"+fn+"\n");
                                        jta.setCaretPosition(jta.getText().length());
                                }
                        } catch (Exception e) {
                                synchronized (jta) {
                                        jta.append("SocChannelServerError:\n"+e.toString()+"\n");
                                        jta.setCaretPosition(jta.getText().length());
                                }
                        }
                }
        }
        // NIO AsynchronousServerSocketChannel
        public class AsynServer extends Thread {
            public AsynServer(int port) {
                        this.port = port;
                }
                private int port;
        public void run( ) {
         try {
               asynSvr = AsynchronousServerSocketChannel.open();
               asynSvr.bind(new InetSocketAddress(port));
               while (true) (new AsynBean(asynSvr.accept().get())).start();
         } catch (Exception e) { }
        }
        }
        // NIO Downloading AsynchronousSocketChannel Thread
        private class AsynBean extends Thread {
                public AsynBean(AsynchronousSocketChannel soc) {
                        this.soc = soc;
                }
                private AsynchronousSocketChannel soc;
                public void run() {
                        try {
                                long be = System.currentTimeMillis();
                                ByteBuffer wbuf = ByteBuffer.allocateDirect(4096);
                                int le = soc.read(wbuf).get(); // get the fileName
                                wbuf.flip();
                                byte[] bb = new byte[4096];
                                wbuf.get(bb, 0, le);
                                String fn = new String(bb, 0, le);
                                FileInputStream fi = new FileInputStream(fn);
                                while ((le = fi.read(bb)) > 0) soc.write(ByteBuffer.wrap(bb, 0, le));
                                fi.close();
                                soc.close();
                                be = System.currentTimeMillis() - be;
                                synchronized (jta) {
                                        jta.append("AsynSocChannelServer\nTransferred Time ="+be+
                                                   " mSec. for the File:"+fn+"\n");
                                        jta.setCaretPosition(jta.getText().length());
                                }
                        } catch (Exception e) {
                                synchronized (jta) {
                                        jta.append("AsynSocChannelServerError:\n"+e.toString()+"\n");
                                        jta.setCaretPosition(jta.getText().length());
                                }
                        }
                }
        }
        //
        private JTextField tfsoc, tfnio, tfasyn;
        private JTextArea jta;
        private JButton jb;

        public OmniServer() {
        try { // look for Nimbus...
           UIManager.setLookAndFeel
                    ("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception ex) { }
                JPanel jp = new JPanel();
                JLabel jlsoc = new JLabel("SocServer Port");
                tfsoc = new JTextField("6786", 4);
                JLabel jlnio = new JLabel("SocChannelServer Port");
                tfnio = new JTextField("6787", 4);
                JLabel jlasyn = new JLabel("AsynSocChannelServer Port");
                tfasyn = new JTextField("6789", 4);
                jp.add(jlsoc);
                jp.add(tfsoc);
                jp.add(jlnio);
                jp.add(tfnio);
                jp.add(jlasyn);
                jp.add(tfasyn);
                jta = new JTextArea("OmniServer picks the file you asked for and "+
                                    "transfers it to your Computer.\n");
                jta.setEditable(false);
                JScrollPane jsp = new JScrollPane(jta);
                jsp.setAutoscrolls(true);
                JPanel lp = new JPanel();
        lp.setLayout(new BorderLayout());
        lp.add(jsp, BorderLayout.CENTER);

                jb = new JButton("START");
                jb.setFont(new Font("Times",Font.BOLD,11));
                JPanel pbx = new JPanel();
                pbx.add(jb);
                jb.addActionListener(this);
                add(jp, BorderLayout.NORTH);
                add(lp, BorderLayout.CENTER);
                add(pbx, BorderLayout.SOUTH);
        addWindowListener(
            new WindowAdapter() {
                public void windowClosing(WindowEvent ew){
                    closeAll();
                }
            }
        );
                setSize(700, 250);
                setVisible(true);
        }
        private void closeAll() {
                try {
                        socSvr.close();
                        nioSvr.close();
                        asynSvr.close();
                } catch (Exception e) { }
                System.exit(0);
        }
        private boolean beg = true;
        public void actionPerformed(ActionEvent e) {
                if (beg) {
                        beg = false;
                        jb.setText("EXIT");
                        tfsoc.setEditable(false);
                        tfnio.setEditable(false);
                        tfasyn.setEditable(false);
                        (new SocServer(Integer.parseInt(tfsoc.getText().trim()))).start();
                        (new NIOServer(Integer.parseInt(tfnio.getText().trim()))).start();
                        (new AsynServer(Integer.parseInt(tfasyn.getText().trim()))).start();
                } else closeAll();
        }
        public static void main(String... a) {
                new OmniServer();
        }
}
...cont
 
Sửa lần cuối:
  • Like
Reactions: burmy

Joe

Thành viên VIP
21/1/13
2,736
1,256
113
...cont
and the OmniClient differs slightly from OmniServer. OmniClient offers you different accessing combinations:
- Access button: Socket, SocChannel and AsynSocChannel
- ComboBox: The Server you want to access
Example: ComboBox is 6787 (ServerSocketChannel) and you hit the button Socket: You download the requested file as Client with Socket-technique and the serving server is the ServerSocketChannel with port 6787.
PHP:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.nio.*;
import java.awt.event.*;
import java.nio.channels.*;
//
import javax.swing.*;
// Joe - Congdongjava.com/forum
public class OmniClient extends JFrame implements ActionListener {
        private JTextField tfsoc, tfnio, tfasyn, file;
        private JComboBox<String> cBox;
        private JButton jbs, jbn, jba;
        private JTextArea jta;
        private String host;
        private JPanel pbx;

        public OmniClient(String host) {
                this.host = host;
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        try { // look for Nimbus...
           UIManager.setLookAndFeel
                    ("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception ex) { }
                JPanel jp = new JPanel();
                JLabel jlsoc = new JLabel("SocServer Port");
                tfsoc = new JTextField("6786", 4);
                JLabel jlnio = new JLabel("SocChannelServer Port");
                tfnio = new JTextField("6787", 4);
                JLabel jlasyn = new JLabel("AsynSocChannelServer Port");
                tfasyn = new JTextField("6789", 4);
                jp.add(jlsoc);
                jp.add(tfsoc);
                jp.add(jlnio);
                jp.add(tfnio);
                jp.add(jlasyn);
                jp.add(tfasyn);
                jta = new JTextArea("OmniClient downloads a file from a selected WebServer\n");

                jta.setEditable(false);
                JScrollPane jsp = new JScrollPane(jta);
                jsp.setAutoscrolls(true);
                JPanel lp = new JPanel();
        lp.setLayout(new BorderLayout());
        lp.add(jsp, BorderLayout.CENTER);
           
                jbs = new JButton("START");
                jbs.setFont(new Font("Times",Font.BOLD,11));
                jbn = new JButton("SocChannel");
                jbn.setFont(new Font("Times",Font.BOLD,11));
                jba = new JButton("AsynSocChannel");
                jba.setFont(new Font("Times",Font.BOLD,11));
                file = new JTextField("/media/Data/test/Coding/test.txt", 20);
                pbx = new JPanel();
                pbx.add(jbs);

                jbs.addActionListener(this);
                jbn.addActionListener(this);
                jba.addActionListener(this);
                add(jp, BorderLayout.NORTH);
                add(lp, BorderLayout.CENTER);
                add(pbx, BorderLayout.SOUTH);
                setSize(800, 250);
                setVisible(true);
        }

        private int ps, pn, pa;
        private boolean beg = true;

        public void actionPerformed(ActionEvent e) {
                if (beg) {
                        beg = false;
                        jbs.setText("Socket");
                        tfsoc.setEditable(false);
                        tfnio.setEditable(false);
                        tfasyn.setEditable(false);
                        ps = Integer.parseInt(tfsoc.getText().trim());
                        pn = Integer.parseInt(tfnio.getText().trim());
                        pa = Integer.parseInt(tfasyn.getText().trim());
                        cBox = new JComboBox<String>((ps+"!"+pn+"!"+pa).split("!"));
                        cBox.setFont(new Font("Times",Font.BOLD,11));
                        JLabel jlp = new JLabel("to ServerPort");
                        JLabel jlf = new JLabel("for");
                        pbx.add(jbn);
                        pbx.add(jba);
                        pbx.add(jlp);
                        pbx.add(cBox);
                        pbx.add(jlf);
                        pbx.add(file);
                        repaint();
                        validate();
                        return;
                }
                String fn = file.getText().trim();
                if (fn.length() == 0) {
                        jta.append("Error: Missing file name\n");
                        return;
                }
                JButton jb = (JButton)e.getSource();
                int p = cBox.getSelectedIndex();
                if (p == 0) p = ps;
                else if (p == 1) p = pn;
                else p = pa;
                //
                if (jb == jbs) goSoc(fn, p);
                else if (jb == jbn) goNIO(fn, p);
                else goAsyn(fn, p);
        }
        // NIO AsynchronousSocketChannel
        public void goAsyn(String fn, int port) {
                try {
                        int le = fn.indexOf(".");
                        String fd = fn.substring(0, le)+"_A"+fn.substring(le, fn.length());
                        long be = System.currentTimeMillis();
                        ByteBuffer bbuf = ByteBuffer.allocateDirect(4096);
                        AsynchronousSocketChannel soc = AsynchronousSocketChannel.open();
                        soc.connect(new InetSocketAddress(host, port)).get();
                        soc.write(ByteBuffer.wrap(fn.getBytes())); // send file name
                        byte[] bb = new byte[4096];
                        FileOutputStream fo = new FileOutputStream(fd, false);
                        while ((le = soc.read(bbuf).get()) != -1) {
                   bbuf.flip();
                                bbuf.get(bb, 0, le);
                                fo.write(bb, 0, le);
                                bbuf.clear();
                        }
                        fo.flush();
                        fo.close();
                        soc.close();
                        be = System.currentTimeMillis() - be;
                        jta.append("- AsynSocketChannel-File:"+fn+"\nis downloaded as "+
                                   fd+", t="+be+" mSec.\n");
                } catch (Exception e) {
                        jta.append("AsynSocketChannelError:\n"+e.toString()+"\n");
                }
                jta.setCaretPosition(jta.getText().length());
        }
        // NIO SocketChannel
        public void goNIO(String fn, int port) {
                try {
                        int le = fn.indexOf(".");
                        String fd = fn.substring(0, le)+"_C"+fn.substring(le, fn.length());
                        long be = System.currentTimeMillis();
                        ByteBuffer bbuf = ByteBuffer.allocateDirect(4096);
                        SocketChannel soc = SocketChannel.open(new InetSocketAddress(host, port));
                        soc.write(ByteBuffer.wrap(fn.getBytes())); // send file name
                        byte[] bb = new byte[4096];
                        FileOutputStream fo = new FileOutputStream(fd, false);
                        while ((le = soc.read(bbuf)) != -1) {
                   bbuf.flip();
                                bbuf.get(bb, 0, le);
                                fo.write(bb, 0, le);
                                bbuf.clear();
                        }
                        fo.flush();
                        fo.close();
                        soc.close();
                        be = System.currentTimeMillis() - be;
                        jta.append("- SocketChannel-File:"+fn+"\nis downloaded as "+
                                   fd+", t="+be+" mSec.\n");
                } catch (Exception e) {
                        jta.append("SocketChannelError:\n"+e.toString()+"\n");
                }
                jta.setCaretPosition(jta.getText().length());
        }
        // Classic Socket
        public void goSoc(String fn, int port) {
                try {
                        int le = fn.indexOf(".");
                        String fd = fn.substring(0, le)+"_S"+fn.substring(le, fn.length());
                        long be = System.currentTimeMillis();
                        Socket soc = new Socket(host, port);
                        InputStream inp = soc.getInputStream();
                        OutputStream out = soc.getOutputStream();
                        out.write(fn.getBytes()); // send file name
                        out.flush();
                        byte[] bb = new byte[4096];
                        FileOutputStream fo = new FileOutputStream(fd, false);
                        for (int i = inp.read(bb); i > 0; i = inp.read(bb)) fo.write(bb, 0, i);
                        fo.flush();
                        fo.close();
                        inp.close();
                        out.close();
                        soc.close();
                        be = System.currentTimeMillis() - be;
                        jta.append("- Socket-File:"+fn+"\nis downloaded as "+
                                   fd+", t="+be+" mSec.\n");
                } catch (Exception e) {
                        jta.append("SocketError:\n"+e.toString()+"\n");
                }
                jta.setCaretPosition(jta.getText().length());
        }
        //
        public static void main(String... a) {
                new OmniClient(a.length == 1?a[0]:"localhost");
        }
}
Enjoy the tangles of OmniServer and OmniClient=))
 

Attachments

Sửa lần cuối: