一个简单的多线程服务器例子

一个简单的多线程服务器例子

中国移动允许我们可以通过短信编辑一些指令发送给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 msgs = new HashMap();
        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 msgs;

    public MultiThread(Socket socket, Map 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
查询结果:没有该消息

你可能感兴趣的:(Java程序语言)