java仿QQ聊天室群聊(快速写一个简易QQ)
首先分析一下要实现多人的群聊的效果,即一个人说一句话,其他所有加入聊天的人都能够收到某某某说了balabala,同时说话的人自己也能够看到自己刚刚说了什么。接下来考虑在计算机中,两个人聊天是怎么实现信息交互的:并不是两个人直接说话,而是中间有一个“中转站”类似,每个人所说的信息,都先经过这个中转站,再由中转站发出去。(计算机采用这种方式可以方便处理信息,尤其当信息较多较复杂的时候)而这个中转站叫.
【mie haha的博客】转载请注明出处(万分感谢!):
https://blog.csdn.net/qq_40315080/article/details/83052689
用java写聊天室实现群聊很简单,理清思路大概只需15min。
首先分析一下要实现多人的群聊,是要实现什么效果。结合QQ微信,群聊即一个人说一句话,其他所有加入聊天的人都能够收到某某某说了balabala,同时说话的人自己也能够看到自己刚刚说了什么。
接下来考虑在计算机中,两个人聊天是怎么实现信息交互的:并不是两个人直接说话,而是中间有一个“中转站”类似,每个人所说的信息,都先经过这个中转站,再由中转站发出去。(计算机采用这种方式可以方便处理信息,尤其当信息较多较复杂的时候)而这个中转站叫服务器,在java中用Serversocket来声明。每个服务器都需要在一个端口运行,在创建服务器serversocket时应指定它在计算机具体哪个端口运行。(如果不知道端口知识,只需知道这个指定的端口范围只能为1024到49151中即可)每一个连接上服务器的就是聊天的人,即客户端,在java中用socket来声明这个连接。
回到实现群聊:
先创建一个服务器serversocket,接下来创建多个连接实现多个客户端。每个客户端都支持输入语句,假设现在A客户端输入语句B,然后在自己这个客户端输出you said:B,在其他连接的客户端输出A said B。群聊实现。
你会发现以上过程存在两个问题:
1.每个客户端可以说的话(输入)应当没有数量限制,即想输多少条就输多少条。
实现很简单,对每个客户端把输入信息和处理信息写在while(true)循环中即可不断地进 行输入要说的话并群聊输出。
2.可以连接的客户端应当没有数量限制,即想连接几个就连接几个。实现很简单,把生成连接socket写在循环while(true)中即可不停的根据需要产生客户端而不会受到数量限制停止,前面讲大鱼吃小鱼时讲过要实现几个相同又相互独立的对象,将它们用线程实现即可。
现在开始写代码:
先创建服务器,这里我设置运行端口为6666,创建完服务器,用循环不停地产生客户端线程。这里为了实现在群聊中的其他客户端能够看到消息是谁发出的,在创建客户端时用count计数给客户端编号。每个客户端内应包含与服务器的连接,用户名,密码(这里还没涉及到,后面完善代码增加用户登录和注册功能时需要使用),所发出过的所有信息等等。所以需要一个用户User类,来描述客户,而不仅仅只是客户端与服务器的连接socket。所以先写User类,再创建服务器和客户端。
User类实现
public class User {
//输入的顺序编号
public int num;
//用户名称
private String name;
//用户密码
private String password;
//用户连接
public Socket socket;
//此人所有消息
private ArrayList<String> userinforlist = new ArrayList<String>();
public User(Socket socket,String name,String password){
this.socket=socket;
this.name=name;
this.password=password;
}
public User(Socket socket,ArrayList<String> userinbforlist,int num){
this.socket=socket;
this.userinforlist=userinforlist;
this.num=num;
}
public void save(String s){
userinforlist.add(s);
}
public String getname(){
return name;
}
public String getpassword(){
return password;
}
}
程序开始,先创建服务器,再用while(true)不停创建线程客户端
//创建服务器类,之后在主函数中用该类声明该类的对象
public class sever {
//一个服务器
private ServerSocket serverSocket;
//private ArrayList<Socket> socketlist = new ArrayList<Socket>();
//所有客户端
private ArrayList<User> userlist = new ArrayList<User>();
//在服务器的对话方法中完成在客户端写下信息,捕捉客户端信息,再次在客户端写下信息的功能
public void talk() {
try {
//选择端口创建服务器
serverSocket = new ServerSocket(6666);
int count=0;
//创建使用者列表
ArrayList<String> userlist = new ArrayList<String>();
//循环创建线程
while(true){
//连入的用户数+1
count++;
//创建连接
Socket conn = serverSocket.accept();
//创建该连接对应用户所有消息存储
ArrayList<String> userinforlist = new ArrayList<String>();
//创建用户
User user = new User(conn,userinforlist,count);
//添加用户
this.userlist.add(user);
//为用户创建线程
TTread thread = new TTread(conn,serverSocket,user,this.userlist);
//线程运行
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//创建服务器,让服务器开始对话工作
public static void main(String[] args){
sever s = new sever();
s.talk();
}
}
接下来实现每个客户端输入信息,显示已发消息并发出群聊,每个客户端都是一个线程,所以在线程中来写。(注释掉的代码是还不完善的用来实判断登录是否成功的判断,与群聊实现无关,可以先不看)
public class TTread extends Thread {
//服务器
private ServerSocket serversocket;
//客户端
private Socket conn;
//所有客户端信息
private ArrayList<User> userlist = new ArrayList<User>();
//当前客户端
private User user;
public TTread(Socket conn,ServerSocket serversocket,User user,ArrayList<User> userlist) {
//当前客户端
this.conn=conn;
//服务器
this.serversocket=serversocket;
//当前客户端所有信息
this.user=user;
//所有用户端
this.userlist=userlist;
}
public void run() {
try {
InputStream filein = conn.getInputStream();
OutputStream out = conn.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(filein));
out.write("欢迎!\r\n".getBytes());
out.flush();
while (true) {
Handsocket handle= new Handsocket(serversocket, conn, userlist,user);
String guestinformation = reader.readLine();
String type,name,password;
//~前为类型
//type=guestinformation.split("~")[0];
//System.out.println(type);
//~和&间为名字
//name=guestinformation.split("~")[1].split("&")[0];
//&后面为密码
//password=guestinformation.split("~")[1].split("&")[1];
//waitcheck wc = new waitcheck(conn,name,password);//创建待检查成员
//wc.check(type);
out.write(("you said:" + new String(guestinformation)).getBytes());
out.write(new String("\r\n").getBytes());
handle.send_to_all(guestinformation);//发出群聊消息
//用户信息
user.save(guestinformation);//把消息存入该用户输入的所有信息中
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面的代码中有一行用来发出群聊消息的代码,接下来对他进行具体实现:
public class Handsocket{
//当前服务器
private ServerSocket socket;
//当前客户端
private Socket thissocket;
//所有客户端
private ArrayList<User> userlist;
//当前用户
private User user;
public Handsocket(ServerSocket socket,Socket thissocket,ArrayList<User> userlist,User user){
this.socket=socket;
this.thissocket=thissocket;
this.userlist=userlist;
this.user=user;
}
//群发消息
public void send_to_all(String s){
for(int i=0;i<userlist.size();i++){
if(userlist.get(i)!=user){
try{
OutputStream out = userlist.get(i).socket.getOutputStream();
String nnum = ""+user.num;
out.write(nnum.getBytes());
out.write((" said:" + new String(s)).getBytes());
out.write(new String("\r\n").getBytes());
}
catch(SocketException e){
e.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
好的现在所有已完全实现。
接下来运行检测一下,检测方法:同时按住Windows键和字母R键,打开“运行”,输入cmd,再输入telnet localhost 6666(6666是以上代码所用的服务器端口)表示连接自己的电脑6666端口,即连接上了代码中的服务器。此时已经生成一个客户端。重复操作可以生成多个客户端。每个客户端都可以输入信息,观察其他客户端的输出情况(当你在一个客户端输入信息,其他客户端有没有输出谁说了什么),检测群聊是否实现。
群聊实现完成。
后面可能会继续出实现聊天室其他功能的文章。
这个版本没有加界面,看起来不太美观,如果需要界面可参考这一篇:https://blog.csdn.net/qq_40315080/article/details/88830295
以上代码全部完整,可直接运行,如有错误或不完善的地方,欢迎指出。
更多推荐
所有评论(0)