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

   日期:2020-07-02     浏览:96    评论:0    
核心提示: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();
			}
		}
	}

}

五、运行结果展示:

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


结语:技术无他,唯有熟尔。知其然,也知其所以然;不要着急,你想要的,岁月都会给你。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服