• Java学习笔记(3)----网络套接字服务器多线程版本


      本例给出一个客户端程序和一个服务器程序。客户端向服务器发送数据。服务器接收数据,并用它来生成一个结果,然后将这个结果返回给客户端。客户端在控制台上显示结果。在本例中,客户端发送的数据是圆的半径,服务器生成的结果是圆的面积。

      客户端通过输出流套接字的 DataOuputStream 发送半径,服务器通过输入流套接字的 DataInputStream 接收半径。服务器计算面积,然后,通过输出流套接字的 DataOutputStream 把它发送给客户端,客户端通过输入流套接字的 DataInputStream 接收面积。服务器和客户端程序在下面的程序清单中给出。

    //Server.java

    package src;
    
    import java.awt.BorderLayout;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Date;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    
    public class Server extends JFrame {
        private JTextArea jta=new JTextArea();
        private ExecutorService executor=Executors.newCachedThreadPool();
        
        public static void main(String[] args){
            new Server();
        }
        
        public Server(){
            setLayout(new BorderLayout());
            add(new JScrollPane(jta),BorderLayout.CENTER);
            setTitle("Server");
            setSize(500, 300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setVisible(true);
            
            try{
                ServerSocket serverSocket=new ServerSocket(8000);
                jta.append("Server started at "+new Date()+'
    ');
                while(true){
                    Socket socket=serverSocket.accept();
                    executor.execute(new Task(socket));    //对接收到的新的连接,启动一个新的线程
                }
            }
            catch(IOException ex){
                System.err.println(ex);
            }
        finally{
            executor.shutdown();
        }
        }
        
        private class Task implements Runnable{
            private Socket socket;
            
            public Task(Socket socket){
                this.socket=socket;
            }
    
            @Override
            public void run() {  //在线程中执行对客户端的应答
                // TODO Auto-generated method stub
                try{
                    DataInputStream inputFromClient=new DataInputStream(socket.getInputStream());
                    DataOutputStream outputToClient=new DataOutputStream(socket.getOutputStream());
                    while(true){
                        double radius=inputFromClient.readDouble();
                        double area=radius*radius*Math.PI;
                        outputToClient.writeDouble(area);
                        jta.append("########  From client -["+socket.getInetAddress()+":"+socket.getPort()+"]-Radius = "+radius+"
    ");
                        jta.append("********  Area is----    "+area+'
    ');
                    }
                }
                catch(IOException ex){
                    System.err.println(ex);
                }
            }
            
        }
    }    

    //Client.java

    package src;
    
    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    public class Client extends JFrame {
        private JTextField jtf=new JTextField();
        private JTextArea jta=new JTextArea();
        private DataOutputStream toServer;
        private DataInputStream fromServer;
        private Socket socket;
        
        public static void main(String args[]){
            new Client();
        }
        
        public Client(){
            JPanel panel=new JPanel();
            panel.setLayout(new BorderLayout());
            panel.add(new JLabel("Enter radius"),BorderLayout.WEST);
            panel.add(jtf, BorderLayout.CENTER);
            jtf.setHorizontalAlignment(JTextField.RIGHT);
            setLayout(new BorderLayout());
            add(panel,BorderLayout.NORTH);
            add(new JScrollPane(jta), BorderLayout.CENTER);
            jtf.addActionListener(new TextFieldListener());//some thing wrong
            
            setTitle("Client");
            setSize(500, 300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setVisible(true);
            try{
                socket=new Socket("localhost",8000);
                fromServer=new DataInputStream(socket.getInputStream());
                toServer=new DataOutputStream(socket.getOutputStream());
                
            }
            catch(IOException ex){
                jta.append(ex.toString()+'
    ');
            }
        }
        private class TextFieldListener implements ActionListener{
    
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                try{
                    double radius=Double.parseDouble(jtf.getText().trim());
                    toServer.writeDouble(radius);
                    toServer.flush();
                    
                    double area=fromServer.readDouble();
                    jta.append("----------- Radius is "+radius+'
    ');
                    jta.append("$$$$$$$$$$$ From server -["+socket.getInetAddress()+":"+socket.getPort()+"] Area= "+area+'
    ');
                }
                catch(IOException ex){
                    System.err.println(ex);
                }
            }
            
        }
    }

    运行效果:

  • 相关阅读:
    zoj1654二分图
    zoj1314无源汇有上下界最大流
    zoj2788最小割
    zoj2587唯一最小割
    poj1815最小割
    Loader之一:基本原理
    Fragment之三:根据屏幕尺寸加载不同的Fragment
    Fragment之一:Fragment入门
    Github android客户端源代码分析之一:环境搭建
    如何在Eclipse中查看Android API源码以及support包源码
  • 原文地址:https://www.cnblogs.com/dongling/p/5748620.html
Copyright © 2020-2023  润新知