zoukankan      html  css  js  c++  java
  • java网络编程(二)可中断套接字

    参考资料:java核心技术 卷II

    为中断套接字操作,可使用java.nio包提供的SocketChannel类。可以使用如下方式打开SocketChannel:

    SocketChannel channel = SocketChannel.open(new InetSocketAddress(host, port));

    java实现如下:

    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{
        //private static final long serialVersionUID = 1L;
        public InterruptibleSocketFrame(){
            setSize(WIDTH,HEIGHT);//设置窗体大小
            setTitle("InterruptibleSocketTest");
    
            JPanel northpJPanel =new JPanel();
            add(northpJPanel,BorderLayout.NORTH);//对容器进行定位
    
            messages=new JTextArea(); //JTextArea类,是一个显示纯文本的多行区域
            add(new JScrollPane(messages)); //JScrollPane类,为数据源提供一个窗口
            interruptilButton=new JButton("Interruptilbel");//JButton类,按钮
            blockingButton=new JButton("Blocking");
    
            northpJPanel.add(interruptilButton);//将button添加到窗口中
            northpJPanel.add(blockingButton);
            
            interruptilButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event){
                    interruptilButton.setEnabled(false);
                    blockingButton.setEnabled(false);//blocking按钮变成不可用
                    cancelButton.setEnabled(true); //cancelButton按钮变成可用
                    connectThread=new Thread(new Runnable(){//创建新线程
                        public void run() {
                            try{
                                connectInterruptibly();
                            } catch (Exception e) {
                                messages.append("
    InterruptibleSocketTest.connectInterruptibly: "+e);
                            }
                        }
                    });
                    connectThread.start();
                }
            });
            blockingButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    interruptilButton.setEnabled(false);
                    blockingButton.setEnabled(false);
                    cancelButton.setEnabled(true);
                    connectThread=new Thread(new Runnable(){
                        public void run() {
                            try {
                                connectBlocking();
                            } catch (IOException e) {
                                messages.append("
    InterruptibleSocketTest.connectblocking: "+e);
                            }
                        }
                    });
                    connectThread.start();
                }
            });
            
            cancelButton =new JButton("Cancel");
            cancelButton.setEnabled(false);
            northpJPanel.add(cancelButton);
            cancelButton.addActionListener(new ActionListener() {//点击cancel按钮来中断线程
                public void actionPerformed(ActionEvent e) {
                    connectThread.interrupt();
                    cancelButton.setEnabled(false);
                    
                }
            });
            server =new TestServer(); //自定义的TestServer类
            new Thread(server).start();
            
        }
        /**
         * 连接到测试服务器,使用可中断I/O
         */
        public void connectInterruptibly() throws IOException{
            messages.append("Interruptible:
    ");
            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("
    ");
                    }
                }
            }finally{
                channel.close();
                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        messages.append("Channel closed
    ");
                        interruptilButton.setEnabled(true);
                        blockingButton.setEnabled(true);
                    }
                });
            }
        }
        /**
         * 连接到测试服务器,使用阻塞I/O
         */
        public void connectBlocking() throws IOException{
            messages.append("Blocking:
    ");
            Socket socket=new Socket("localhost",8189); //不可中断套接字
            try {
                in=new Scanner(socket.getInputStream());
                while (!Thread.currentThread().isInterrupted()){
                    messages.append("Reading ");
                    if(in.hasNextLine()){
                        String line=in.nextLine();
                        messages.append(line);
                        messages.append("
    ");
                    }
                }
            }finally{
                socket.close();
                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        messages.append("Socket closed
    ");
                        interruptilButton.setEnabled(true);
                        blockingButton.setEnabled(true);
                    }
                });
            }
        }
        /**
         * 一个监听8189端口的多线程服务器,并向客户端连续发送数字,并在发送10个数字之后挂起
         */
        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 (Exception e) {
                    messages.append("
    TestServer.run: "+e);
                }
            }
    
        }
        /**
         * 处理客户端用于服务器套接字链接的客户端输入
         */
        class TestServerHandler implements Runnable{
            public TestServerHandler(Socket i){
                incoming=i;
            }
            public void run() {
                try {
                    OutputStream outputStream=incoming.getOutputStream();
                    PrintWriter out=new PrintWriter(outputStream,true /*autoFulsh*/);
                    while(counter < 100){
                        counter++;
                        if(counter <= 10) 
                            out.println(counter);
                        Thread.sleep(100);
                    }
                    incoming.close();
                    messages.append("Closing Server
    ");
                } catch (Exception e) {
                    messages.append("
    TestServerHandler.run: "+e);
                }
    
            }
            private Socket incoming;
            private int counter;
        }
    
        private Scanner in;
        private JTextArea messages; 
        private JButton interruptilButton,blockingButton,cancelButton;
        private Thread connectThread;
        private TestServer server;
    
        public static final int WIDTH=550;
        public static final int HEIGHT=400;
    }

    执行程序,点击Blocking,在第一批的10个数字执行过程中,点击cancel,仍会继续输完10个数字,Interruptible和Blocking两个按钮变不可用。点击Interruptible可中断线程。

  • 相关阅读:
    LeetCode_326. Power of Three
    LeetCode_303. Range Sum Query
    LeetCode_299. Bulls and Cows
    LeetCode_292. Nim Game
    LeetCode_290. Word Pattern
    LeetCode_283. Move Zeroes
    LeetCode_278. First Bad Version
    LeetCode_268. Missing Number
    LeetCode_263. Ugly Number
    LeetCode_258. Add Digits
  • 原文地址:https://www.cnblogs.com/zeroingToOne/p/7906541.html
Copyright © 2011-2022 走看看