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");
}
}
}
}
简单运行结果截图
: