aReflection_01GetAllConstructorDemo
package com.se.aReflection;
import com.se.util.ReflectionUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
/**
* 获取所有构造器,包括私有的
*
* 修饰词对应的是常量,public-->1 private-->2 protected-->4 default-->0
* static-->8 final-->16 synchronized-->32
*/
public class _01GetAllConstructorDemo {
public static void main(String[] args) {
try {
//先获取描述类的对象,描述Person类型
Class<?> aClass = Class.forName(ReflectionUtil.getClassNameString());
//获取所有的构造器
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
//遍历数组
for (Constructor<?> constructor : declaredConstructors) {
//获取构造器的修饰词
System.out.println("构造器的修饰词:" + constructor.getModifiers());
//获取构造器的名字
System.out.println("构造器的名字:" + constructor.getName());
//获取构造器的参数
Parameter[] parameters = constructor.getParameters();
for (Parameter parameter : parameters) {
//获取参数的类型
System.out.println("参数类型:" + parameter.getType());
//获取参数的名字
System.out.println("参数名字:" + parameter.getName());
}
System.out.println("-------------------");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
aReflection_02GetAllMethodDemo
package com.se.aReflection;
import com.se.util.ReflectionUtil;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* 获取一个类中所有的方法,包括私有的
*/
public class _02GetAllMethodDemo {
public static void main(String[] args) {
try {
//获取描述Person类的类对象
Class<?> aClass = Class.forName(ReflectionUtil.getClassNameString());
//获取类中所有的方法
Method[] methods = aClass.getDeclaredMethods();
//遍历
for (Method mothod : methods) {
//获取方法修饰词
System.out.println("修饰词" + mothod.getModifiers());
//方法的返回值类型
System.out.println("返回值类型" + mothod.getReturnType());
//方法名
System.out.println("方法名" + mothod.getName());
//方法参数
Parameter[] parameters = mothod.getParameters();
for (Parameter parameter : parameters) {
//参数类型
System.out.println("参数类型" + parameter.getType());
}
System.out.println("-------------------");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
bMember_01GetFieldDemo
package com.se.bMember;
import com.se.util.ReflectionUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 获取成员变量
*/
public class _01GetFieldDemo {
public static void main(String[] args) {
try {
//获取描述类对象
Class<?> aClass = Class.forName(ReflectionUtil.getClassNameString());
//获取所有的属性
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
//获取属性修饰词
System.out.println("修饰词" + declaredField.getModifiers());
//属性的类型
System.out.println("属性类型" + declaredField.getType());
//属性名
System.out.println("属性名" + declaredField.getName());
}
//假如不知道有哪些方法。可以指定一个方法名,查看是否返回
//注意,如果获取不到方法,抛异常,NoSuchMethodException
Method sleep = aClass.getMethod("setName", String.class);
//假如不知道有那些属性,可以指定一个属性,查看是否返回正确
//注意,如果获取不到属性,抛异常,NoSuchFieldException
Field gender = aClass.getField("gender");
} catch (Exception e) {
e.printStackTrace();
}
}
}
cInstance_01PersonDemo
package com.se.cInstance;
import com.se.util.ReflectionUtil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 使用反射机制实例化一个对象
*/
public class _01PersonDemo {
public static void main(String[] args) {
try {
//获取Person的描述类对象
Class<?> aClass = Class.forName(ReflectionUtil.getClassNameString());
//调用无参构造器,实例化对象
Object o = aClass.newInstance();
//实例化之后,属性都是默认值,需要进行初始化,覆盖默认值
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
//将属性与对象关联上,并赋值
name.set(o, "小蕊");
Field age = aClass.getDeclaredField("age");
age.setAccessible(true);
age.set(o, 22);
Field gender = aClass.getDeclaredField("gender");
gender.setAccessible(true);
gender.set(o, '女');
System.out.println(o);
//调用setGender方法,将'女'覆盖
Method setGender = aClass.getMethod("setGender", char.class);
//方法与对象关联,使用invoke方法
setGender.invoke(o, '男');
System.out.println(o);
//调用sleep方法
Method sleep = aClass.getDeclaredMethod("sleep", String.class);
sleep.setAccessible(true);
sleep.invoke(o, "床");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
dNetApi_01InetAddressDemo
package com.se.dNetApi;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
/**
* 常用API之InetAddress
* 1. 该类用于描述一台机器的Ip和主机信息
* 2. 常用方法:
* - static InetAddress getLocalHost()
* - static InetAddress getByName(String host)
* - String getHostAddress()
* - String getHostName()
*/
public class _01InetAddressDemo {
public static void main(String[] args) {
try {
//获取一个描述本机信息的InetAddress对象 主机名称和ip地址
InetAddress addr = InetAddress.getLocalHost();
System.out.println(addr);
//获取里面的主机名称
System.out.println("主机名称:"+addr.getHostName());
//获取里面的ip地址 192.168.1.121
System.out.println("ip地址:"+addr.getHostAddress());
//Ip的字节序列形式 [-64, -88, 1, 121]
System.out.println("Ip的字节序列形式:"+ Arrays.toString(addr.getAddress()));
//描述本机的形式有:127.0.0.1 localhost 具体IP
InetAddress inet1= InetAddress.getByName("192.168.1.121");
System.out.println(inet1);
//获取其他域名或者指定IP信息
InetAddress inet2 = InetAddress.getByName("www.baidu.com");
System.out.println(inet2.getHostAddress());
System.out.println(inet2.getHostName());
//获取域名对应的所有的主机
InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com");
System.out.println(allByName.length);
for (InetAddress inetAddress : allByName) {
System.out.println(inetAddress.getHostAddress());
}
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}
dNetApi_02ServerSocketDemo
package com.se.dNetApi;
import com.sun.xml.internal.ws.addressing.WsaActionUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/**
* TCP通信协议的服务端API
* 1. ServerSocket 用来描述TCP的服务端
* 2. 常用构造器:
* ServerSocket(int port): 用于指定一个端口号,返回具体的实例
* 3. 常用方法:
* - setSoTimeout(int timeout): 用于定义一个阻塞的超时时间,单位毫秒,超时报异常,
* 设置为0时候表示不超时,一直等待,默认为0
* - accept(): 阻塞方法,监听客户端的连接请求,监听到则返回一个Socket对象,表示客户端的连接
*/
public class _02ServerSocketDemo {
public static void main(String[] args) {
//创建一个服务端的实例对象,指定端口号,必须是没使用过的
try {
ServerSocket server = new ServerSocket(9999);
//设置超时时间,单位毫秒
// server.setSoTimeout(10000);
System.out.println("等待客户端连接,仅限10s");
//调用accpet方法,监听客户端连接,是否连接服务器
Socket socket =server.accept();//如果指定了超时时间,改时间没客户端连接,跑SocketException异常
System.out.println("客户端连接成功");
//获取输入流,等待客户端传入信息
InputStream inputStream = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(inputStream, "utf-8"));
String info = br.readLine();
System.out.println("客户端发送的信息:"+info);
// System.out.println("服务端ip:"+server.getInetAddress().getHostAddress());
// System.out.println("服务端ip:"+server.getInetAddress().getHostName());
// System.out.println("详细内容:"+server.getLocalSocketAddress());
// System.out.println("正在使用的端口号:"+server.getLocalPort());
// System.out.println("服务端是否关闭:"+server.isClosed());
// System.out.println("超时时间:"+server.getSoTimeout());
// System.out.println("服务器绑定的端口号是否正确:"+server.isBound());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
dNetApi_03SocketDemo
package com.se.dNetApi;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
/**
* TCP通信协议额客户端API
* 1. Socket这个类用于描述TCP的客户端
* 2. 常用构造器:
* Socket(String hostname,int port): 指定想要的服务器的IP和端口号
* Socket(InetAddress address,int port): 指定服务器的地址和端口号
*/
public class _03SocketDemo {
public static void main(String[] args) {
//指定服务器的IP和端口号,返回一个客户的Socket对象,连接服务器
try {
// Socket socket = new Socket("127.0.0.1", 9999);
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
OutputStream out = socket.getOutputStream();
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(out, "utf-8"), true);
pw.println("你好");
//测试客户端的其他方法
InetAddress inerAddress = socket.getInetAddress();
System.out.println("远程服务端的地址信息:" + inerAddress);
InetAddress localAddress = socket.getLocalAddress();
System.out.println("客户端的地址信息:" + localAddress);
int localPort = socket.getLocalPort();
System.out.println("客户端自己分配用于通信的端口号:" + localPort);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
util_RefilectionUtil
package com.se.util;
import java.io.FileReader;
import java.util.Properties;
/**
* 反射工具类
*/
public class ReflectionUtil {
public static String getClassNameString() {
String classname = null;
try (FileReader fr = new FileReader("./reflection.properties")) {
//创建一个Propeties配置文件对象
Properties prop = new Properties();
//调用方法读取流里的信息,就会自动将配置文件里的key=value对封装到自身
prop.load(fr);
//解析prop,通过key获取value
classname = prop.getProperty("classname");
} catch (Exception e) {
e.printStackTrace();
}
return classname;
}
public static void main(String[] args) {
System.out.println(ReflectionUtil.getClassNameString());
}
}
VO_Person
package com.se.VO;
public class Person {
private String name;
private int age;
private char gender;
public Person(){}
private Person(String name){
this.name = name;
}
public Person(String name,int age,char gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
private void sleep(String obj){
System.out.println(name+"喜欢躺在"+obj+"睡觉");
}
}
refiection.properties
classname=com.se.VO.Person
chat_ChatClient
package com.se.chat;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/**
* 聊天客户端
*/
public class ChatClient {
//定义一个TCP通信协议的客户端属性
private Socket socket;
public ChatClient() {
//获取Socket对象,同时向服务器端发起连接请求,连接失败:ConnectException
try {
socket = new Socket("localhost", 8888);
} catch (IOException e) {
System.out.println("服务器崩溃");
}
}
//聊天的主方法
private void start() {
//获取向服务器发送信息的输入流对象
try {
//获取一个服务端信息的处理器任务
Runnable task = new GetServerInfoHandler();
Thread thread = new Thread(task);
thread.start();
//获取向服务器发送信息的输出流对象
OutputStream outputStream = socket.getOutputStream();
//封装成字节缓存流,可以按行输出
PrintWriter out = new PrintWriter(
new OutputStreamWriter(
outputStream, "utf-8"), true);
//使用控制台扫描对象类型,不断扫描控制台上的文字
Scanner scan = new Scanner(System.in);
//设置昵称
System.out.println("请输入你的昵称");
String nickname = scan.nextLine();
//将昵称发送到服务端,服务器校验昵称是否可用
out.println(nickname);
System.out.println("开始聊天");
while (true) {
String info = scan.nextLine();
//将扫描的信息发送服务端
out.println(info);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
//创建具体的聊天对象
ChatClient client = new ChatClient();
//调用客户端的主方法
client.start();
}
class GetServerInfoHandler implements Runnable {
public void run() {
try {
//获取向服务器发送信息的输入流对象
InputStream inputStream = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(inputStream, "utf-8"));
//获取自己的昵称
String nickname = br.readLine();
System.out.println("你的昵称为:" + nickname);
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
chat_ChatServer
package com.se.chat;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 聊天服务器
*/
public class ChatServer {
//定义一次TCP通信协议的服务端属性
private ServerSocket server;
//添加一个Map属性,存储多个客户端的标识与输出流对象 Map集合(散列表)
private Map<String, PrintWriter> allOut;
public ChatServer(int port) {
try {
server = new ServerSocket(port);
//给Map集合赋值
allOut = new HashMap<String, PrintWriter>();
} catch (IOException e) {
System.out.println("服务器启动失败");
}
}
//聊天的主方法
private void start() {
try {
while (true) {
System.out.println("等待服务器连接");
Socket socket = server.accept();
System.out.println("一个客户端连接");
//每连接一个客户端的Socket对象,将其放入并发线程
Runnable task = new GetClientInfoHandler(socket);
Thread thread = new Thread(task);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//创建一个具体的服务器对象
ChatServer chatServer = new ChatServer(8888);
//调用聊天的主方法
chatServer.start();
}
//定义一个处理客户端信息的线程
class GetClientInfoHandler implements Runnable {
//因为run方法使用了socket对象,所以需要将socket对象作为参数
//所有在该类中添加属性,run方法可以访问属性
private Socket socket;
//提供一个构造器,将start方法中的局部变量socket传进来,给属性赋值, 这样,run方法中使用的socket就是
//start方法中的局部变量指向的对象
public GetClientInfoHandler(Socket socket) {
this.socket = socket;
}
public void run() {
String nickname = null;
try {
//通过服务端的Socket对象,获取输入流,接收客户端发送信息
InputStream inputStream = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(inputStream, "utf-8"));
//通过服务端的Socket对象,获取输出流,将信息返回给客户端
OutputStream outputStream = socket.getOutputStream();
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(outputStream, "utf-8"), true);
//先获取客户端的昵称
nickname = br.readLine();
//循环判断昵称是否重复
while (allOut.containsKey(nickname)) {
nickname = nickname + Math.random();
}
//将昵称返回给客户端
pw.println(nickname);
//将昵称与输出流对象存入Map集合
allOut.put(nickname, pw);
System.out.println("在线人数" + allOut.size());
//循环打印客户端发来的信息
String info = "";
while ((info = br.readLine()) != null) {
//将信息info发送给所有客户端
sendToAllClient(nickname, info);
}
} catch (IOException e) {
System.out.println("一个客户端退出");
//删除相应的键值对
allOut.remove(nickname);
System.out.println("在线人数" + allOut.size());
}
}
}
public void sendToAllClient(String nickname, String info) {
//遍历Map里的所有输出流,来发送info信息
Set<String> nicks = allOut.keySet();
for (String nick : nicks) {
//获取输出流,然后发送信息
PrintWriter writer = allOut.get(nick);
writer.println(nickname + "说:" + info);
}
}
}
chat1_ChatClient
package com.se.chat1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.Socket;
import java.util.Map;
public class ChatClient extends JPanel {
/* 定义Sockt属性 */
private Socket socket;
private JTextArea welcomeArea;
/* 添加面板属性,三个文本框属性 */
private JTextArea showText;
private JTextArea countText;
private JTextArea nameText;
private JTextArea oneText;
private JTextArea inputText;
private JTextArea noticeText;
private JButton sendButton;
private JButton closeButton;
public ChatClient() {
try {
// 取消面板的默认布局, 使用绝对布局,即使用坐标方式进行布局
this.setLayout(null);
// 修改面板的背景颜色
this.setBackground(new Color(200, 200, 200));
//调用自己封装的初始化布局方式
initLayout();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化自己的页面布局:
* 1. 头部布局
* 2. 上半部身体的布局
* 3. 下半部身体的布局
* 4. 聊天输入框的布局
* 5. 两个按钮的布局
*/
public void initLayout(){
headLayout();
body1Layout();
body2Layout();
chatInputArea();
buttonArea();
}
/**
* 两个按钮的布局
*/
private void buttonArea() {
//两个按钮
firstButton();
lastButton();
}
/**
* 第二个按钮"关闭"的布局
*/
private void lastButton() {
closeButton = new JButton("关闭");
closeButton.setBounds(590,550,65,35);
this.add(closeButton);
closeButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int option = JOptionPane.showConfirmDialog(null, "您确定要离开吗");
if (option == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
}
/**
* 第一个按钮“发送”的布局
*/
private void firstButton() {
sendButton = new JButton("发送");
sendButton.setBounds(590,505,65,35);
this.add(sendButton);
}
/**
* 聊天窗口的布局
*/
private void chatInputArea() {
//5. 输入窗口
inputText = new JTextArea("输入框");
inputText.setBackground(new Color(238,238,238));
inputText.setBounds(5,495,580,100);
this.add(inputText);
}
/**
* 私聊的内容显示窗口,与群公告窗口的布局
*/
private void body2Layout() {
//5. 私聊显示窗口
oneText = new JTextArea("私聊显示窗口");
oneText.setBackground(new Color(238,238,238));
oneText.setBounds(5,390,650,100);
this.add(oneText);
//6. 公告窗口
noticeText = new JTextArea("公告");
noticeText.setBackground(new Color(238,238,238));
noticeText.setBounds(660,390,235,205);
this.add(noticeText);
}
/**
* 公共聊天显示窗口和在线成员列表窗口的布局
*/
private void body1Layout() {
//3. 公共聊天组件
showText = new JTextArea("公共聊天显示窗口");
showText.setBackground(new Color(238,238,238));
showText.setEditable(false);// 设置不可编辑
showText.setBounds(5,30,650,355);
//为showText设置滚动条
JScrollPane scroll = new JScrollPane(showText);
//设置垂直滚动
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(scroll);
this.add(showText);
//4. 成员列表组件
nameText = new JTextArea("成员列表");
nameText.setBounds(660,30,235,355);
nameText.setBackground(new Color(238,238,238));
JScrollPane scroll1 = new JScrollPane(nameText);
scroll1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(scroll1);
this.add(nameText);
}
/**
* 欢迎语,与 人数在线统计的 布局
*/
private void headLayout() {
//0. 欢迎logo
welcomeArea = new JTextArea("欢迎进入聊天室,您的昵称是:");
welcomeArea.setBackground(new Color(200, 200, 200));
welcomeArea.setEditable(false);
welcomeArea.setBounds(5,5,650,20);
this.add(welcomeArea);
//1. 统计人数组件
countText = new JTextArea("在线人数:");
countText.setBackground(new Color(200,200,200));
countText.setBounds(660,5,235,20);
this.add(countText);
}
public void start(){
}
public static void main(String[] args) {
//启动聊天窗口
JFrame frame = new JFrame("聊天室");
frame.setUndecorated(true);
frame.setSize(900,600);
//创建一个面板
ChatClient panel = new ChatClient();
frame.setContentPane(panel);
frame.setLocationRelativeTo(null);
// frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//启动聊天
panel.start();
}
}
chat1_ChatServer
package com.se.chat1;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 聊天服务器
*/
public class ChatServer {
//定义一个TCP通信协议的服务端属性
private ServerSocket server;
//添加一个Map属性,用于存储多个客户端的标识与输出流对象。 Map集合(散列表)
private Map<String,PrintWriter> allOut;
public ChatServer(int port) {
try {
server = new ServerSocket(port);
//给map集合赋值
allOut = new HashMap<String,PrintWriter>();
} catch (IOException e) {
System.out.println("---服务器启动失败---");
}
}
/**
* 聊天的主方法
*/
public void start() {
try {
while (true) {
System.out.println("---等待客户端连接---");
Socket socket = server.accept();
System.out.println("---一个客户端连接上了---");
//每获取一个客户端的Socket对象,就应该将其放入一个并发线程中
Runnable task = new GetClientInfoHandler(socket);
Thread thread = new Thread(task);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//创建一个具体的服务器对象
ChatServer chatServer = new ChatServer(8888);
//调用聊天的主方法
chatServer.start();
}
/**
* 定义一个处理客户端信息的处理器,即一个任务体
*/
class GetClientInfoHandler implements Runnable {
//因为run方法中使用了 start方法中的socket局部变量
//所以可以在该类中添加一个属性,run方法中可以访问该类的属性
private Socket socket;
//提供一个构造器,将start方法中的局部变量socket传进来,给属性赋值, 这样,run方法中使用的socket就是
//start方法中的局部变量指向的对象
public GetClientInfoHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
String nickname = null;
try {
//通过服务端的Socket对象,获取输入流,接受客户端发送过来的数据
InputStream inputStream = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(inputStream,"utf-8"));
//通过服务端的Socket对象,获取输出流,将信息返回给客户端
OutputStream outputStream = socket.getOutputStream();
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(outputStream,"utf-8"),true);
//先获取客户端的昵称
nickname = br.readLine();
//判断是否已经被占用,如果已经被占用,加后缀
while(allOut.containsKey(nickname)){
nickname = nickname+Math.random();
}
//将昵称告诉客户端
pw.println(nickname);
//将输出流添加到Map集合中
allOut.put(nickname,pw);
System.out.println("-----在线人数:"+allOut.size()+"--------");
//循环打印客户端发送过来的信息
String info = "";
while ((info = br.readLine()) != null) {
// 如果信息不是以@开头的,说明不是私聊,将信息info发送到所有的客户端里
if(!info.startsWith("@")){
sendToAllClient(nickname,info);
}else{
sendToOneClient(nickname,info);
}
}
} catch (IOException e) {
System.out.println("---一个客户端离线了---");
//删除对应的键值对
allOut.remove(nickname);
System.out.println("-----在线人数:"+allOut.size()+"--------");
}
}
}
public void sendToOneClient(String nickname, String info) {
//获取要私聊的对象名称
//获取第一个冒号的下标
int index = info.indexOf(":");
String toNickName = info.substring(1, index);
//找到对应的流对象
PrintWriter printWriter = allOut.get(toNickName);
printWriter.println(nickname+"对你说:"+info.substring(index+1));
}
public void sendToAllClient(String nickname, String info) {
//遍历Map里的所有输出流,来发送info信息
Set<String> nicks = allOut.keySet();
for (String nick : nicks) {
//获取对应的输出流,然后发送信息
PrintWriter writer = allOut.get(nick);
writer.println(nickname+"说:"+info);
}
}
}