Java通信原理(4)——消息收发

本文详细讲解了如何在通信架构中实现客户端消息的收发。首先,通过创建服务器和初始化哈希表来记录用户。接着,当客户端发送JSON数据包时,服务器解析数据获取消息内容,并保存发送者的Socket。然后,服务器根据收件人ID查找对应Socket,编码信息并转发给接收者。最终,展示了两个客户端同时在线并进行消息交互的场景。
摘要由CSDN通过智能技术生成

一、概述

           之前介绍了通信架构的服务器如何搭建以及客户端界面如何实现,本章着重讲解如何实现客户端消息收发。

二、原理

        之前文章中所介绍的服务器模型可以接受客户端发送过来的消息(InputStream)如果想让客户端接收到消息,我们可以再服务端将消息发送给客户端,因此我们需要再服务端新建一个输出流,这就是消息收发的基本思想。

三、实现过程

     1、用户列表:关于消息接收我们可以新建一个服务器,并且初始化一个哈希表用于记录连接到该服务器的用户

public class ClientMessage {
    ServerSocket serverSocket;
    int port = 25000;//设置消息收发服务器端口

    public ClientMessage(){}

    public void initServer(){
        //日志信息输出
        System.out.println(new TimeGetter().getTime() + "MessageSaveServer is started <- ClientMessage");
        try {
            serverSocket = new ServerSocket(port);
            while (true) {
                //新建消息接收线程
                new InfoGetter(serverSocket).start();
          
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


class InfoGetter extends Thread implements Config {
    ServerSocket serverSocket;
    //新建一个哈希表用于保存连接到该服务器用户的Socket对象
    HashMap<String , Socket> msgServerLink = new HashMap<>();

    public InfoGetter() {
    }

    public InfoGetter(ServerSocket serverSocket) {
        this.serverSocket = serverSocket;
    }

    @Override
    public void run() {
    }
}

   

     2、消息接收:当客户端将消息发送后,会生成一个JSON数据包并发送给服务器。服务器通过解析JSON数据包获取到收、发人的消息和内容,并将连接到该服务器的用户Socket保存起来。

public void run() {
        Socket accept = null;
        while (true) {
            try {
                //创建消息接收对象
                accept = serverSocket.accept();
                //创建输入流
                InputStream in = accept.getInputStream();
                int len = in.read();
                byte [] data = new byte[len];
                in.read(data);
                String message = new String(data , 0 , len);
                //客户端发送消息时将以JSON形式发送,因此需要解析JSON信息
                JSONObject js = new JSONObject(message);
                String userID = (String) js.get("userID");//发送人ID
                String friendID = (String) js.get("friendID");//接收人ID
                String content = (String) js.get("content");//消息内容
                String sendTime = (String) js.get("sendTime");//发送时间
                int msgType = (Integer) js.get("msgType");//发送消息的类型
                //判断用户是否在线并保存其Socket对象
                if(!msgServerLink.containsKey(userID)){
                    msgServerLink.put(userID , accept);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

     3、消息转发:当服务器转发消息时,先从解析后的JSON数据中读取收件人ID,并从哈希表中查询到收件人的Socket,并初始化该Socket的OutputStream,最后将信息进行编码转发

public void run() {
        Socket accept = null;
        while (true) {
            try {
                accept = serverSocket.accept();
                InputStream in = accept.getInputStream();
                int len = in.read();
                byte [] data = new byte[len];
                in.read(data);
                String message = new String(data , 0 , len);
                MessageCheck messageCheck = new MessageCheck();
                messageCheck.saveMessage(message);
                JSONObject js = new JSONObject(message);
                String userID = (String) js.get("userID");
                String friendID = (String) js.get("friendID");
                String content = (String) js.get("content");
                String sendTime = (String) js.get("sendTime");
                int msgType = (Integer) js.get("msgType");
                InfoCheck info = new InfoCheck();
                String sender = info.getFriendName(friendID);
                if(!msgServerLink.containsKey(userID)){
                    msgServerLink.put(userID , accept);
                }
                //信息编辑,添加发件人信息,消息发送时间以及发送的内容
                String reciveMsg = sendTime + "##" + sender + "##" + content;
                byte [] reciveMessage = reciveMsg.getBytes();
                Socket newAccpet = msgServerLink.get(friendID);
                System.out.println(newAccpet);
                //初始化接收人输出流
                OutputStream out = newAccpet.getOutputStream();
                out.write(reciveMessage.length);
                out.write(reciveMessage);
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 四、运行效果

      1、同时登录两个客户端

     2、打开消息收发界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值