一起聊

项目描述

该项目实现了基于多线程场景下集用户注册、私聊、群聊、退出功能于一体的一个简单的多人聊天系统,暂时还没有实现图形界面。当多个客户端向服务器发起连接请求时,服务端采用线程池的方式提高用户访问效率。

如果客户端输入的内容是以 “register” 开头的,那么则认为服务器要处理的是用户注册业务,并将该用户加入到聊天列表中;如果客户端输入的内容是以 “G” 开头的,那么则认为服务器要处理的是用户所发出的群聊任务,把群聊信息发送给除了自己以外的所有用户;如果客户端输入的内容是以 “P” 开头的,那么认为服务器要处理的是用户发出的私聊请求,将该信息转发给指定用户。

使用技术

Java基础、Socket编程、多线程

项目设计图

在这里插入图片描述

项目源码

https://github.com/jihaojiemo/chat-room

项目中遇到的问题

项目中实现了单线程和多线程两部分。

客户端:

  • 单线程客户端存在的问题:
    客户端必须输入之后才会收到服务器发回的信息;发送和读取相互影响,而且只能读取、发送一次。
  • 改进:
    把客户端的读和写分为两个线程,并且循环,不断的读取用户的输入发送给服务器,不断的读取服务器发来的数据。写线程多了一个终止条件,如果用户输入“byebye”则退出连接。

服务端:

  • 单线程服务器端存在的问题:
    只能接收一个客户端的连接请求。
  • 改进:
    要能接收多个客户端的连接请求(需要使用多线程)。

难点:服务器如何实现一个多线程???
每当有客户端连接的时候,调用 accept 方法获取到一个 Socket 的时候,就把它包装成一个线程去处理,不同的客户端在不同的子线程中处理,这样互相也不会影响(想到了线程池!)。

接着还会产生一个问题:

如何保存多个客户端的连接???
每个用户名对应一个 Socket 的连接,使用 Map 来保存,key 存储用户名,value 存储连接到服务器的 Socket 对象。并且要用到的 ConcurrentHashMap,用ConcurrentHashMap,线程安全,多个线程可以同时注册到服务器,线程不安全的话,可能会导致 userName 重复的话,前面的就会失效,用 ConcurrentHashMap 保证多线程注册时候用户名一定是一个。

总结一下:
服务器的功能:处理用户的输入并完成客户端数据的转发
客户端的功能:通过终端输入向服务器发送数据

项目测试
功能测试:

1. 正常功能:
前提条件:网络状态良好+客户端服务器已建立好连接
(1)可以多个用户同时进入聊天室;
(2)用户可以成功注册,并且可以将该用户加入到用户列表中,在线用户数加一;
(3)在多个用户进入聊天室后,该用户群发一条消息,所有除了自己之外的用户都能收到;其他用户所发送的所有消息,该用户也都能正常收到;
(4)在多个用户进入到聊天室后,该用户向某个用户私发一条消息后,私聊对象能收到该消息;
(5)用户输入“byebye”之后,正常下线,且在线用户数减一。

2. 异常功能:
(1)网络不佳或者客户端服务器尚未建立连接,不能正常进入聊天室;
(2)若用户已注册后再重复注册,显示“您已注册过了,无需重复注册”;
(3)私聊对象不在线或者未注册过,提示用户“您要私聊的用户不存在”;
(4)用户输入不正确,例如区分注册、私聊、群聊的标识符输入错误,提醒用户重新输入;
(5)用户发送的消息的类型不正确,长度不符合规则,包含特殊字符时,都提示用户重新输入。

性能测试:

(1)最多有多少个用户可以进入聊天室(最大用户数);
(2)多个用户同时发送消息,收到消息的延时(服务器的平均响应时间)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值