Mega Code Archive

 
Categories / Java / Network Protocol
 

This program shows how to interrupt a socket channel

/*    This program is a part of the companion code for Core Java 8th ed.    (http://horstmann.com/corejava)    This program is free software: you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program.  If not, see <http://www.gnu.org/licenses/>. */ import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.SocketChannel; import java.util.Scanner; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; /**  * This program shows how to interrupt a socket channel.  * @author Cay Horstmann  * @version 1.01 2007-06-25  */ public class InterruptibleSocketTest {    public static void main(String[] args)    {       EventQueue.invokeLater(new Runnable()          {             public void run()             {                JFrame frame = new InterruptibleSocketFrame();                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                frame.setVisible(true);             }          });    } } class InterruptibleSocketFrame extends JFrame {    public InterruptibleSocketFrame()    {       setSize(WIDTH, HEIGHT);       setTitle("InterruptibleSocketTest");       JPanel northPanel = new JPanel();       add(northPanel, BorderLayout.NORTH);       messages = new JTextArea();       add(new JScrollPane(messages));       interruptibleButton = new JButton("Interruptible");       blockingButton = new JButton("Blocking");       northPanel.add(interruptibleButton);       northPanel.add(blockingButton);       interruptibleButton.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                interruptibleButton.setEnabled(false);                blockingButton.setEnabled(false);                cancelButton.setEnabled(true);                connectThread = new Thread(new Runnable()                   {                      public void run()                      {                         try                         {                            connectInterruptibly();                         }                         catch (IOException e)                         {                            messages.append("\nInterruptibleSocketTest.connectInterruptibly: " + e);                         }                      }                   });                connectThread.start();             }          });       blockingButton.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                interruptibleButton.setEnabled(false);                blockingButton.setEnabled(false);                cancelButton.setEnabled(true);                connectThread = new Thread(new Runnable()                   {                      public void run()                      {                         try                         {                            connectBlocking();                         }                         catch (IOException e)                         {                            messages.append("\nInterruptibleSocketTest.connectBlocking: " + e);                         }                      }                   });                connectThread.start();             }          });       cancelButton = new JButton("Cancel");       cancelButton.setEnabled(false);       northPanel.add(cancelButton);       cancelButton.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                connectThread.interrupt();                cancelButton.setEnabled(false);             }          });       server = new TestServer();       new Thread(server).start();    }    /**     * Connects to the test server, using interruptible I/O     */    public void connectInterruptibly() throws IOException    {       messages.append("Interruptible:\n");       SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", 8189));       try       {          in = new Scanner(channel);          while (!Thread.currentThread().isInterrupted())          {             messages.append("Reading ");             if (in.hasNextLine())             {                String line = in.nextLine();                messages.append(line);                messages.append("\n");             }          }       }       finally       {          channel.close();          EventQueue.invokeLater(new Runnable()          {             public void run()             {                messages.append("Channel closed\n");                interruptibleButton.setEnabled(true);                blockingButton.setEnabled(true);             }          });       }    }    /**     * Connects to the test server, using blocking I/O     */    public void connectBlocking() throws IOException    {       messages.append("Blocking:\n");       Socket sock = new Socket("localhost", 8189);       try       {          in = new Scanner(sock.getInputStream());          while (!Thread.currentThread().isInterrupted())          {             messages.append("Reading ");             if (in.hasNextLine())             {                String line = in.nextLine();                messages.append(line);                messages.append("\n");             }          }       }       finally       {          sock.close();          EventQueue.invokeLater(new Runnable()          {             public void run()             {                messages.append("Socket closed\n");                interruptibleButton.setEnabled(true);                blockingButton.setEnabled(true);             }          });             }    }    /**     * A multithreaded server that listens to port 8189 and sends numbers to the client, simulating a     * hanging server after 10 numbers.     */    class TestServer implements Runnable    {       public void run()       {          try          {             ServerSocket s = new ServerSocket(8189);             while (true)             {                Socket incoming = s.accept();                Runnable r = new TestServerHandler(incoming);                Thread t = new Thread(r);                t.start();             }          }          catch (IOException e)          {             messages.append("\nTestServer.run: " + e);          }       }    }    /**     * This class handles the client input for one server socket connection.     */    class TestServerHandler implements Runnable    {       /**        * Constructs a handler.        * @param i the incoming socket        */       public TestServerHandler(Socket i)       {          incoming = i;       }       public void run()       {          try          {             OutputStream outStream = incoming.getOutputStream();             PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);             while (counter < 100)             {                counter++;                if (counter <= 10) out.println(counter);                Thread.sleep(100);             }             incoming.close();             messages.append("Closing server\n");          }          catch (Exception e)          {             messages.append("\nTestServerHandler.run: " + e);          }       }       private Socket incoming;       private int counter;    }    private Scanner in;    private JButton interruptibleButton;    private JButton blockingButton;    private JButton cancelButton;    private JTextArea messages;    private TestServer server;    private Thread connectThread;    public static final int WIDTH = 300;    public static final int HEIGHT = 300; }