一个简单的多线程服务器例子
中国移动允许我们可以通过短信编辑一些指令发送给10086,以获取一些办理的业务信息。下边以一个类似的例子来模拟服务器。
建立一个多线程服务器端,能够处理不同客户端的连接,以查询客户端发送的指令内容。假设客户端可以向服务器端查询一人向另一人发送的短消息,发送指令格式如*#MSG#*from|to,则服务器端的实现:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 服务器端
*
* @author 小明
*
*/
public class Server {
public static void main(String[] args) throws Exception {
/* Map暂存所有消息 */
Map<String, String> msgs = new HashMap<String, String>();
msgs.put("tom to jery", "hello jery");
msgs.put("jery to tom", "hello tom");
msgs.put("kate to tom", "don't forget me this weekend");
// 服务器监听3334端口
ServerSocket server = new ServerSocket(3334);
while (true) { // 循环监听客户端连接
Socket socket = server.accept(); // 接收客户端连接
new Thread(new MultiThread(socket, msgs)).start(); // 启动新线程处理该客户端连接
}
}
}
/**
* 多线程类,处理每个客户端连接的请求与响应
*
* @author 小明
*/
class MultiThread implements Runnable {
/**
* 套接字对象
*/
private Socket socket;
/**
* 存放消息的集合
*/
private Map<String, String> msgs;
public MultiThread(Socket socket, Map<String, String> msgs) {
super();
this.socket = socket;
this.msgs = msgs;
}
@Override
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
while (true) { // 循环处理套接字输入输出流数据
String str = in.readUTF(); // 读取客户端发送的请求
// 正则表达式,用于判断客户端发送的请求格式是否正确,以及获取请求内容
Pattern pattern = Pattern
.compile("[*]#(\\w{3})#[*](\\w*)[|](\\w*)"); // *#MSG#*tom|lily
Matcher matcher = pattern.matcher(str);
if (matcher.matches()) { // 客户端请求格式正确
matcher.reset();
matcher.find(); // 查找分组
String cmd = matcher.group(1); // 请求内容
if ("MSG".equalsIgnoreCase(cmd)) { // 请求内容为"MSG"
String from = matcher.group(2); // 来自
String to = matcher.group(3); // 到
String msg = msgs.get(from + " to " + to);
if (msg != null)
out.writeUTF(from + " to " + to + ", msg : " + msg); // 向客户端写
else
out.writeUTF("没有该消息");
out.flush();
}
} else {
out.writeUTF("输入数据格式有误");
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端的简单实现:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
/**
* 客户端
*
* @author 小明
*
*/
public class Client {
public static void main(String[] args) throws Exception {
Scanner input = new Scanner(System.in);
Socket socket = new Socket("localhost", 3334); // 建立连接套接字
final DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
while (true) {
System.out.print("输入查询内容:");
String request = input.next();
out.writeUTF(request); // 发送查询请求
out.flush();
try {
String answer = in.readUTF(); // 读取查询结果
System.out.println("查询结果:" + answer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果(客户端):
输入查询内容:*#MSG#*tom|jery 查询结果:tom to jery, msg : hello jery 输入查询内容:*#MSG#*kate|tom 查询结果:kate to tom, msg : don't forget me this weekend 输入查询内容:*#MSG#*tom|kate 查询结果:没有该消息