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;

/**
 * 
 * @author 静寞小森(沧海森林)
 *
 */

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

	/**
	 * @param args
	 */
	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;
/**
 * 
 * @author 静寞小森(沧海森林)
 *
 */

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;
/**
 * 
 * @author 静寞小森 Socket运算,客户端界面
 * 
 */
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");
			}
		}
	}
}
简单运行结果截图

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值