多用户通信系统---服务器

 

ConnectThread
package Chat.Service;

import Chat.common.Message;
import Chat.common.MessageType;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

/**
 * @author whlie(true){learn}
 * 和客户端保持通信
 */
public class ConnectThread extends Thread {
    private Socket socket;
    //连接到服务端的用户ID
    private String userId;

    public ConnectThread( String userId,Socket socket) {
        this.socket = socket;
        this.userId = userId;
    }

    public Socket getSocket() {
        return socket;
    }

    @Override
    public void run() {
        while(true){
            System.out.println("客户端"+userId+"与服务器正在通信...");
            try {
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message message=(Message) ois.readObject();
                //根据message的类型做相应的业务处理
                if (message.getMesType().equals(MessageType.GET_ONLINE)){
                    //在线用户列表
                    System.out.println(message.getSender()+"请求在线用户列表");
                    String online = Manage.getOnline();
                    //构建message对象返回给客户端
                    Message message2 = new Message();
                    message2.setMesType(MessageType.RET_ONLINE);
                    message2.setContent(online);
                    message2.setGetter(message.getSender());
                    //通过输出流发往客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(message2);
                }else if(message.getMesType().equals(MessageType.COMMON_MES)){
                    //获取目标线程
                    ConnectThread ct = Manage.get(message.getGetter());
                    //根据线程得到输出流
                    ObjectOutputStream oos = new ObjectOutputStream(ct.getSocket().getOutputStream());
                    //转发,如果不在线可以保存在数据库,实现离线留言
                    oos.writeObject(message);
                }else if(message.getMesType().equals(MessageType.GROUP)){
                    //遍历管理线程的集合,得到所有线程的socket,把message进行转发
                    HashMap<String, ConnectThread> hm = Manage.getHm();
                    Iterator<String> iterator = hm.keySet().iterator();
                    while(iterator.hasNext()){
                        //取出在线用户id
                        String onlineid = iterator.next().toString();
                        //排除自身
                        if (!onlineid.equals(message.getSender())){
                            ObjectOutputStream oos = new ObjectOutputStream
                                    (hm.get(onlineid).getSocket().getOutputStream());
                            oos.writeObject(message);
                        }
                    }
                }else if (message.getMesType().equals(MessageType.FILE)){
                    ObjectOutputStream oos = new ObjectOutputStream(Manage.get(message.getGetter()).getSocket().getOutputStream());
                    oos.writeObject(message);
                } else if(message.getMesType().equals(MessageType.EXIT)){
                    Manage.remove(message.getSender());
                    socket.close();
                    System.out.println(message.getSender()+"已退出登录");
                    break;
                } else{
                    System.out.println("1");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
Manage
package Chat.Service;

import java.util.HashMap;
import java.util.Iterator;

/**
 * @author whlie(true){learn}
 * 用于管理和客户端之间的通信
 */
public class Manage {
    private static HashMap<String,ConnectThread> hm=new HashMap<>();
    public static void add(String userId,ConnectThread connectThread){
        hm.put(userId,connectThread);
    }
    public static void remove(String userId){
        hm.remove(userId);
    }
    public static HashMap<String, ConnectThread> getHm() {
        return hm;
    }

    public static ConnectThread get(String userId){
        return hm.get(userId);
    }
    //返回在线用户列表
    public static String getOnline(){
        //遍历集合,迭代器
        Iterator<String> iterator = hm.keySet().iterator();
        String online="";
        while(iterator.hasNext()){
            online += iterator.next().toString()+" ";
        }
        return online;
    }
}
SendtoAll
package Chat.Service;

import Chat.common.Message;
import Chat.common.MessageType;
import Chat.tool.Utility;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;

/**
 * @author whlie(true){learn}
 */
public class SendtoAll implements Runnable{
    private Scanner scanner = new Scanner(System.in);
    @Override
    public void run() {
        while (true){
            System.out.println("请输入推送内容:(输入exit退出)");
            String news= Utility.readString(100);
            if (news.equals("exit")){
                break;
            }
            //构建消息并群发
            Message message = new Message();
            message.setSender("服务器");
            message.setContent(news);
            message.setMesType(MessageType.GROUP);
            message.setSenderTime(new Date().toString());
            System.out.println("服务器推送消息:"+news);

            //遍历所有的通信通道的到socket
            HashMap<String, ConnectThread> hm = Manage.getHm();
            Iterator<String> iterator = hm.keySet().iterator();
            while(iterator.hasNext()){
                String id = iterator.next().toString();
                try {
                    ObjectOutputStream oos = new ObjectOutputStream(hm.get(id).getSocket().getOutputStream());
                    oos.writeObject(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
Service
package Chat.Service;

import Chat.common.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author whlie(true){learn}
 * 服务器  等待客户端连接  并保持通信
 */
public class Service {
    private ServerSocket ss=null;
    /**
     * 因为还不会数据库所以使用ConcurrentHashMap代替
     * HashM是线程不安全的
     * ConcurrentHashMap是线程安全的,解决并发问题
     */
    private static ConcurrentHashMap<String,User> sql=new ConcurrentHashMap<String,User>();
    //还未实现单点登录
    static{
        sql.put("100",new User("100","123456"));
        sql.put("唐僧",new User("唐僧","123456"));
        sql.put("至尊宝",new User("至尊宝","123456"));
        sql.put("紫霞仙子",new User("紫霞仙子","123456"));
    }
    //验证用户登录
    public boolean check(String userId,String password){
        User user = sql.get(userId);
        if (user==null){
            return false;
        }
        if (!user.getPassword().equals(password)){
            return false;
        }
        return true;
    }
    public Service(){
        System.out.println("服务器在9999端口监听...");
        try {
            ss=new ServerSocket(9999);
            //启动推送
            new Thread(new SendtoAll()).start();
            //因为要一直监听
            while(true){
                //如果没有连接会阻塞在这里
                Socket socket = ss.accept();
                //输入流
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                //输出流
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                //读取客户端发送的User对象
                User user=(User) ois.readObject();
                //用于回复客户端
                Message message = new Message();
                //验证用户是否存在
                if (check(user.getUserId(),user.getPassword())){
                    message.setMesType(MessageType.LONGIN_SUCCESS);
                    //将Message回复给客户端
                    oos.writeObject(message);
                    //创建一个线程与客户端保持通信
                    ConnectThread connectThread = new ConnectThread(user.getUserId(),socket);
                    //启动线程
                    connectThread.start();
                    //加入集合
                    Manage.add(user.getUserId(),connectThread);
                }else {
                    System.out.println("用户"+user.getUserId()+"登录失败");
                    message.setMesType(MessageType.LONGIN_FAIL);
                    oos.writeObject(message);
                    socket.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //如果服务器退出了while说明结束监听,关闭服务器
            try {
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
ServiceView
package Chat;

import Chat.Service.Service;

/**
 * @author whlie(true){learn}
 * 启动服务器
 */
public class ServiceView {
    public static void main(String[] args) {
        new Service();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1while(true){learn}

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值