java学习编程练习(局域网多人聊天功能的实现)

来源:互联网 发布:网页淘宝分享到微信 编辑:程序博客网 时间:2024/06/16 15:12

此题综合了,最近两周学习的IO流、进程、网络传输等知识,基本实现了多人聊天的功能。经过修改封装,有较好的可读性。

设计思路:

1、建立一个进程类Monitor,其成员变量包括Socket的引用、读和写的引用、客户端的编号名字。为每一个客户端建立Monitor的对象并将其放在静态ArrayList中;

2、通过对ArrayList的枚举实现信息的群发和转发;

3、通过匿名类不类分别建立读和写的进程,并以temp2为开关;

4、在主方法中开启进程clossAll(),并通过枚举ArrayList监控对象的开关temp2。当temp2=false时,关闭当前对象的所有通道、进程,同时从ArrayList上删除;

5、服务器有较好的通用性,只需要客户端具有read和write的能力变可以实现通讯;

6、关于乱码,当编码完全采用GBK编码时,可以解决键盘输入乱码的问题。客户端编码必须同服务器编码保持一致。

类Monitor:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.ArrayList;import java.util.Scanner;public class Monitor extends Thread {/** 用于存放Socket连接的对象所在的Monitor */static ArrayList<Monitor> list = new ArrayList<Monitor>();/** 避免nums重复的计数器 */static int cout = 0;/** 服务器全局输入对象 */static Scanner line = new Scanner(System.in);/** 端口编号,用cout进行赋值便于确定对象 */int nums;Socket socket;BufferedReader read;PrintWriter write;String name;boolean temp2 = true;/** * 构造方法 */public Monitor(Socket socket) {this.socket = socket;cout++;nums = cout;try {read = new BufferedReader(new InputStreamReader(socket.getInputStream()));write = new PrintWriter(socket.getOutputStream());} catch (IOException e) {System.out.println(nums + "端口错误!");}this.start();}/** * 开启通道进程 */public void run() {names();reads();writes();}/** *转发连接用户的信息,实现信息同步 */void sendMessage(String str) {for (int i = 0; i < list.size(); i++) {if (nums != list.get(i).nums) {list.get(i).write.println(str);list.get(i).write.flush();}}}/** * 服务台发送信息 */static void sendTo(String str) {if (str != null) {str = "帅的飞起说:" + str;for (int i = 0; i < list.size(); i++) {list.get(i).write.println(str);list.get(i).write.flush();}}}/** * 读取客户端名字 */void names() {write.println("请输入您的名字!");write.flush();boolean temp3 = true;while (temp3) {try {Thread.sleep(100);String str2 = read.readLine();if (str2 != null) {name = str2;temp3 = false;String str4 = "欢迎" + name + "加入聊天室";System.out.println(str4);sendTo(str4);}} catch (IOException e) {System.out.println("录入客户端名字出错");temp2 = false;temp3 = false;} catch (InterruptedException e) {System.out.println("录入客户端名字出错");temp2 = false;temp3 = false;}}}/** * 进程,读取信息并且将信息群发给在线其他人 */void reads() {new Thread(new Runnable() {public void run() {while (temp2) {try {sleep(100);String str = name + "说:" + read.readLine();if (!str.equals(name + "说:")) {System.out.println(str);sendMessage(str);}} catch (IOException e) {System.out.println(name + "读取错误");temp2 = false;} catch (InterruptedException e1) {System.out.println(name + "read读入异常");temp2 = false;}}}}).start();}/** * 进程,群发信息 */void writes() {new Thread(new Runnable() {public void run() {while (temp2) {String str1 = null;try {str1 = line.nextLine();} catch (Exception e) {}sendTo(str1);}}}).start();}/** * 关闭当前对象所有进程:当temp2为false时关闭各种进程 */static void closeAll() {new Thread(new Runnable() {public void run() {boolean temp = true;while (temp) {int i = 0;try {sleep(100);for (; i < list.size(); i++) {if (list.get(i).temp2 == false) {if (list.get(i).read != null) {list.get(i).read.close();}if (list.get(i).write != null) {list.get(i).write.close();}if (list.get(i).socket != null) {list.get(i).socket.close();}String str5 = list.get(i).name + "已退出聊天!";list.remove(i);System.out.println(str5);sendTo(str5);}}} catch (IOException e) {System.out.println("关闭进程" + list.get(i).nums + "出错");} catch (InterruptedException e1) {System.out.println("结束程序:等待错误!");}}}}).start();}}


主方法:

import java.io.IOException;import java.net.ServerSocket;/** * 实现多人聊天功能的服务器,主方法类 */public class Server {/** 当temp1为false时停止服务器 */static boolean temp1 = true;public static void main(String[] args) {try {ServerSocket server = new ServerSocket(7845);Monitor.closeAll();//开启监控程序用于删除在list上过期的对象while (temp1) {Monitor.list.add(new Monitor(server.accept()));//监视等待信号}} catch (IOException e) {System.out.println("端口错误!");}}}

一个简易的客户端:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import java.util.Scanner;public class SerCient {public static void main(String[] args) {try {Scanner str = new Scanner(System.in);Socket socket = new Socket("localhost", 7845);final BufferedReader read = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter write = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));new Thread(new Runnable() {public void run() {while (true) {try {Thread.sleep(100);String str2 = read.readLine();if (str2 != null) {System.out.println( str2);}} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}}}).start();try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}String str3 = str.next();while (!str3.equals("88")) {write.println(str3);write.flush();str3 = str.next();}read.close();write.close();str.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}



0 0
原创粉丝点击