Java中使用Socket完成简单的远程计…

Socket服务端

服务器端使用了继承Tread进行多线程处理,服务程序,具有单独的main()函数进行运行,其中通过调用类中的重写的run()方法

package cn.edu.nwsuaf.cie.qhs.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;



public class SocketServer extends Thread{
    public ServerSocket server = null;
    public Socket client = null;
    public PrintStream out = null;
    public BufferedReader buf = null;

    public SocketServer() {
        try {
            server = new ServerSocket(8888);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void run() {//多线程处理计算部分,提供给多个用户同时使用这一个服务
        // TODO Auto-generated method stub
        while (true) {
            try {
                client = server.accept();
                // String str = "Hello Socket!";
                buf = new BufferedReader(new InputStreamReader(client
                        .getInputStream()));
                double a = Double.parseDouble(buf.readLine().trim());
                char operator = buf.readLine().trim().charAt(0);
                double b = Double.parseDouble(buf.readLine().trim());
                double result = 0;
                switch (operator) {
                case '+':
                    result = a + b;
                    break;
                case '-':
                    result = a - b;
                    break;
                case '*':
                    result = a * b;
                    break;
                case '÷':
                    result = a / b;
                    break;
                case '%':
                    result = a % b;
                    break;
                case '^':
                    result = Math.pow(a, b);
                    break;
                default:
                    result = a + b;
                    break;
                }
                out = new PrintStream(client.getOutputStream());
                out.println(result);
                out.flush();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void closeServer() {
        out.close();
        try {
            client.close();
            server.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

   
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SocketServer server = new SocketServer();
        while(true){
            server.run();
        }
    }

}

Socket客户端连接服务器程序

本程序主要是为界面提供真正运行的类,然后本类会在界面程序中调用。

package cn.edu.nwsuaf.cie.qhs.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;


public class SocketClient {
    private Socket client = null;
    private BufferedReader buf = null;
    private PrintStream out = null;

    public SocketClient() {
    }
    //调用时传回四个参数,分别表示服务器IP地址,第一个运算数,运算符,第二个运算数
    public Double socketCalculate(String ipAddr,double first, char operator, double second) {
        try {
            client = new Socket(ipAddr, 8888);
            buf = new BufferedReader(new InputStreamReader(client
                    .getInputStream()));
            out = new PrintStream(client.getOutputStream());
            out.println(first);
            out.println(operator);
            out.println(second);
            String str = buf.readLine();
            out.flush();
            buf.close();
            out.close();
            client.close();
            client = null;
            return Double.parseDouble(str);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public boolean isConnected() {
        if (client.isConnected())
            return true;
        else
            return false;
    }

    public void connect() {
        SocketAddress addr = client.getRemoteSocketAddress();
        try {
            client.connect(addr);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SocketClient socketClient = new SocketClient();
        System.out.println(socketClient.socketCalculate("127.0.0.1",1, '-', 25));
    }
}

调用客户端程序的用户界面

此程序就是一个界面程序,没有太多的处理,除了其中的正则表达式判断输入的服务器IP是否正确,输入的要计算的输入,是不是正确的数字类型。

【注】Pattern类就是实现了正则表达式判断

package cn.edu.nwsuaf.cie.qhs.socket;

import java.awt.BorderLayout;

public class ClientFrame extends JFrame {
    private char[] listData = { '+', '-', '*', '÷', '%', '^' };
    // 用正则表达式匹配整型、浮点型、double型的数
    private Pattern pattern = Pattern.compile("^\\d+(\\.(\\d+))?$",
            Pattern.MULTILINE);
    // 用正则表达式匹配IP地址(包含基本判断)
    private Pattern pattern1 = Pattern
            .compile(
                    "^((1[0-9][0-9])||(2[0-5][0-5])||([1-9][0-9])||[1-9]\\.)((1[0-9][0-9])||(2[0-5][0-5])||([1-9][0-9])||[0-9]\\.){2}((1[0-9][0-9])||(2[0-5][0-5])||([1-9][0-9])||[1-9])$",
                    Pattern.MULTILINE);

    private JPanel panel = new JPanel(new BorderLayout());
    private JPanel inputPanel = new JPanel(new GridLayout(3, 3, 5, 5));
    private JPanel IPPanel = new JPanel(new GridLayout(1, 5, 5, 5));
    //设置IP的默认值,为本地服务器(127.0.0.1)
    private JLabel IPLabel = new JLabel("IP");
    private JTextField firstField = new JTextField("127", 3);
    private JTextField secondField = new JTextField("0", 3);
    private JTextField thirdField = new JTextField("0", 3);
    private JTextField forthField = new JTextField("1", 3);

    private JLabel addendLabel = new JLabel("第一个运算数");
    private JLabel operatorLabel = new JLabel("运算符");
    private JLabel augendLabel = new JLabel("第二个运算数");
    private JTextField addendField = new JTextField();
    //现在只是提供了这几种计算符,所以选择了使用ComboBox(下拉列表)
    private JComboBox operatorComboBox = new JComboBox();
    private JTextField augendField = new JTextField();

    private JLabel resultLabel = new JLabel("结果:↓");
    private JButton clearButton = new JButton("清空");
    private JButton calButton = new JButton("计算");
    //用一个文本域来显示计算过的结果
    private JTextArea resultArea = new JTextArea(10, 10);
    //创建客户端的后台实际和服务器交互的程序
    private SocketClient client = new SocketClient();

    public ClientFrame() {
        panel.add(IPPanel, BorderLayout.NORTH);
        panel.add(inputPanel, BorderLayout.CENTER);
        panel.add(resultArea, BorderLayout.SOUTH);

        IPPanel.add(IPLabel);
        IPPanel.add(firstField);
        IPPanel.add(secondField);
        IPPanel.add(thirdField);
        IPPanel.add(forthField);

        inputPanel.add(addendLabel);
        inputPanel.add(operatorLabel);
        inputPanel.add(augendLabel);
        inputPanel.add(addendField);
        inputPanel.add(operatorComboBox);
        inputPanel.add(augendField);
        inputPanel.add(resultLabel);
        inputPanel.add(clearButton);
        inputPanel.add(calButton);

        for (char content : listData) {
            operatorComboBox.addItem(content);
        }

       
        clearButton.addActionListener(new ClearActionListener());
        calButton.addActionListener(new CalculateActionListener());

        resultArea.setEditable(false);

        this.setBounds(300, 100, 600, 500);
        this.setMaximumSize(new Dimension(600, 500));
        this.setMinimumSize(new Dimension(600, 500));

        this.getContentPane().add(panel);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        ClientFrame frame = new ClientFrame();
    }

    class ClearActionListener implements ActionListener {
        // 响应“清除”按钮
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            addendField.setText(null);
            augendField.setText(null);
            resultArea.setText(null);
            operatorComboBox.setSelectedIndex(0);
        }
    }

    class CalculateActionListener implements ActionListener {
        // 响应“计算”按钮
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            String firstOne = addendField.getText().trim();
            String secondOne = augendField.getText().trim();
            char operatorChar = listData[operatorComboBox.getSelectedIndex()];
            //如果没有输入两个数,则会判断并提示,没有同时输入两个数时就按下了“计算”按钮
            if (firstOne == null || "".equals(firstOne) || secondOne == null
                    || "".equals(secondOne)) {
                JOptionPane.showMessageDialog(null, "请输入第一个数与第二个数", "空串判断",
                        JOptionPane.ERROR_MESSAGE);
                return;
            } else {
                double addend = 0;
                double augend = 0;
                Matcher matcher1 = pattern.matcher(firstOne);
                Matcher matcher2 = pattern.matcher(secondOne);
                //当两个数都是数字类型时(int,float,double)则进行转换,这里就不要加转换异常的处理,因为正则表达式已经完成了。
                if (matcher1.find() && matcher2.find()) {
                    addend = Double.parseDouble(firstOne);
                    augend = Double.parseDouble(secondOne);
                } else {
                    JOptionPane.showMessageDialog(null, "请在输入框中输入数字", "格式错误",
                            JOptionPane.ERROR_MESSAGE);
                    return;
                }
                // 获得IP
                String ipAddr = firstField.getText().trim() + "."
                        + secondField.getText().trim() + "."
                        + thirdField.getText().trim() + "."
                        + forthField.getText().trim();
                if (ipAddr == null || "".equals(ipAddr)) {
                    ipAddr = "127.0.0.1";
                } else {
                    Matcher matcher = pattern1.matcher(ipAddr);
                    if (matcher.find()) {
                        JOptionPane.showMessageDialog(null,
                                "请输入正确的IP" + ipAddr, "IP错误",
                                JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                }//开始计算,并获得结果追加打印到文本域上
                Double result = client.socketCalculate(ipAddr, addend,
                        operatorChar, augend);
                resultArea.setText(resultArea.getText() + firstOne + " "
                        + operatorChar + " " + " " + secondOne + " = " + result
                        + "\n");
            }
        }
    }
}
简单运行结果截图

你可能感兴趣的:(Java中使用Socket完成简单的远程计…)