欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java网络编程,模拟QQ群聊功能

程序员文章站 2023-11-29 11:12:40
Java网络编程,模拟QQ群聊功能一、网络编程知识点简介:1.C/S架构:Client客户端/Server服务器:涉及到的应用:桌面的应用软件,QQ,王者荣耀涉及到的技术:Socket网络编程2.网络:各个孤立的工作站或主机相连在一起,从而达到资源共享和通信的目的2.1 网络分为局域网和广域网:局域网:在局域网里可以实现数据的共享优点:规模小,容易搭建,传输速度快比如:公司的局域网,学校宿舍里的网络广域网:因特网就是世界范围内最大的广域网(WWW)3.网络协议:*...

Java网络编程,模拟QQ群聊功能

一、网络编程知识点简介:

1.C/S架构:Client客户端/Server服务器:

  • 涉及到的应用:桌面的应用软件,QQ,王者荣耀
  • 涉及到的技术:Socket网络编程

2.网络:

各个孤立的工作站或主机相连在一起,从而达到资源共享和通信的目的

2.1 网络分为局域网和广域网:

局域网:
  1. 在局域网里可以实现数据的共享
  2. 优点:规模小,容易搭建,传输速度快
  3. 比如:公司的局域网,学校宿舍里的网络
广域网:
  1. 因特网就是世界范围内最大的广域网(WWW)

3.网络协议:

  1. ****TCP(Transmis Control Protocol,传输控制协议)—>(面向连接)
  2. ****UDP(User Datagram Protocol,用户数据报协议)—>(面向非连接)

4.端口和套接字:

  1. 端口(port):可以认为是设备与外界通信交流的出口,范围是0-65535之间的整数
  2. Java提供了IP地址的封装类InetAddress,它位于java.net包中,主要封装ip地址

二、题目要求:

实现QQ群聊功能:

  • 客户端之间的聊天,本质是客户端发送一条消息后,由服务器转发到另外的所有客户端

三、简述步骤:

  • 1.在服务器TCPServer类中定义List集合用来存放所有连接进来的客户端
  • 2.ClientThread的run方法中,当构建好PrintWriter对象后,将对象加入到List集合中
  • 3.在接收客户端消息的地方,调用sendMsg方法,将消息发送给除了自己以外的所有的客户端
  • 4.完成sendMsg方法

四、代码实现:

1.创建客户端类:

1.1 封装打开客户端的方法
public class TCPClient01 {
	/*
	 * 封装打开客户端的方法
	 */
	public void open() {
		try {
			//创建客户端,并连接服务器
			Socket client = new Socket("localhost",9999);	
			System.out.println("连接服务器成功!");
			//获取客户端输入流的对象
			InputStream is = client.getInputStream();
			//创建并启动读取服务器发送消息的线程
			new ReadFromServer(is).start();
			//获取客户端输出流对象
			OutputStream os = client.getOutputStream();
			//创建并启动向服务器发送消息的线程
			new WriteToServer(os).start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		TCPClient01 client = new TCPClient01();
		client.open();
	}
}

1.2 封装读取服务器发送消息的线程:
class ReadFromServer extends Thread{
	//封装服务器发送过来消息的输入流
	InputStream is;
	public ReadFromServer(InputStream is) {
		this.is = is;
	}
	
	//重写run方法
	@Override
	public void run() {
		//使用BufferedReader读取服务器的消息
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line = null;
		try {
			//开始读取
			while((line=br.readLine())!=null){
				System.out.println(line);
			}
			//关流
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
				
	}
}
1.3 封装客户端向服务器发送消息的线程:
class WriteToServer extends Thread{
	OutputStream os;
	//客户端向服务器发送消息的输出流
	public WriteToServer(OutputStream os) {
		super();
		this.os=os;
	}
	//重写run方法
	@Override
	public void run() {
		//创建键盘扫描器
		Scanner key = new Scanner(System.in);
		//写入消息
		PrintWriter pw = new PrintWriter(os);
		while(true) {
			//接收用户输入的内容
			String line = key.nextLine();
			//写入
			pw.println(line);
			//强制刷新
			pw.flush();
	
		}
		
	}
	
}


2.创建服务器类:

2.1创建并启动服务器的方法:
public class TCPServer01 {
	//以客户端的昵称作为key值,以发送的消息作为value
	//定义一个变量
	Map<String,PrintWriter> allout;
	/*
	 * 创建并启动服务器的方法
	 */
	public void start() {
		//初始化变量
		allout = new HashMap<String,PrintWriter>();
		
		try {
			//创建服务器
			ServerSocket server  = new ServerSocket(9999);
			System.out.println("服务器启动成功,等待用户接入...");
			//创建while循环,保证服务器一直开启并且一直等待客户端连接
			while(true) {
				//调用accept方法
				Socket client = server.accept();
				//得到连接的客户端的IP地址
				System.out.println("有客户接入,客户的IP为:"+client.getInetAddress());
				//启动线程
				new ClientThread(client,allout).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		TCPServer01 server = new TCPServer01();
		server.start();
	}
}
2.2 向客户端发送消息,接收客户端发送过来的消息
class ClientThread extends Thread{
	//连接到服务器端的客户端
	Socket client;
	Map<String,PrintWriter> allout;	
	public ClientThread(Socket client, Map<String, PrintWriter> allout) {
		super();
		this.client = client;
		this.allout = allout;
	}
	
	@Override
	public void run() {
		try {
			//向客户端发送数据
			//获取输出流对象
			OutputStream out = client.getOutputStream();

			PrintWriter pw = new PrintWriter(out);
			//发消息
			pw.println("~~~欢迎来到云轩棋牌聊天室~~~~");
			pw.println("请先输入您的聊天昵称:");
			//强制刷新
			pw.flush();		
			//接收客户端发送的消息
			InputStream in = client.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in));			
			//获取昵称
			String name = br.readLine();			
			//将客户端输出流对象加入到集合中
			allout.put(name, pw);			
			String line = null;
			while((line=br.readLine())!=null){			
				//向其他所有的客户端发送消息,pw代表当前自己
				sendMsg(name+"说:"+line,pw);
			}
			//关流
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

2.3 向其他所有的客户端发送消息的方法:
private void sendMsg(String line, PrintWriter pw) {
		//遍历map集合
		Set<String> names = allout.keySet();
		for(String name:names){
			//根据key获取到对应的value值
			PrintWriter p = allout.get(name);	
			if(p != pw){						
				p.println(line);
				//刷新
				p.flush();
			}
		}
	}

}

五、运行结果展示:

*温馨提示:运行时,首先启动服务器,然后启动客户端哟

Java网络编程,模拟QQ群聊功能
结语:技术无他,唯有熟尔。知其然,也知其所以然;不要着急,你想要的,岁月都会给你。
Java网络编程,模拟QQ群聊功能

本文地址:https://blog.csdn.net/qq2663020556/article/details/107069408