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);
            }
        }
        
    }
}

运行效果:

原文地址:https://www.cnblogs.com/dongling/p/5748620.html