这个局域网聊天系统,是为了能够在一个没有连接到intent的局域网中,进行聊天的一个程序。本程序包括服务器和客户机两部分,可以实现多人聊天和两个人私聊的一个工具。
开发语言:Java,开发工具:eclipse。
客户机代码如下:
Client.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
public class Client{//客户端
JFrame frame;
JList<String> userList;//列表组件
JTextArea textArea;//文本域
JTextField textField;
JTextField txt_port,txt_Ip,txt_name;
JButton button_start,button_stop,button_send;//连接按钮,断开按钮,发送按钮
JPanel north,south;//上、下面板
JScrollPane rightScroll,leftScroll;//左右滚动面板
JSplitPane centerSplit;//分割面板
DefaultListModel<String> listModel;//点击事件
private boolean crossFire = false;
Socket socket;//套接字
PrintWriter writer;
BufferedReader reader;
MessageThread messageThread;// 负责接收消息的线程
private Map<String, User> onLineUsers = new HashMap<String, User>();// 所有在线用户集合
public void send() {//发送方法
if (!crossFire) {
JOptionPane.showMessageDialog(frame, "Warning!无法连接服务器", "错误",JOptionPane.ERROR_MESSAGE);
return;
}
String message = textField.getText().trim();
if (message == null || message.equals("")) {
JOptionPane.showMessageDialog(frame, "Warning! 消息不能为空!", "错误",JOptionPane.ERROR_MESSAGE);
return;
}
sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message);
textField.setText(null);
}
public Client() {//创建构造方法
textArea = new JTextArea();
textArea.setEditable(false);//设置文本域不可读
textArea.setForeground(Color.RED);//设置背景颜色位红色
textField = new JTextField();
txt_port = new JTextField();//端口号
txt_Ip = new JTextField();//服务器IP
txt_name = new JTextField();//用户名
button_start = new JButton("连接");
button_stop = new JButton("断开");
button_send = new JButton("发送");
listModel = new DefaultListModel<String>();
userList = new JList<String>(listModel);
north = new JPanel();
north.setLayout(new GridLayout(1, 4));//设置布局方式
north.add(new JLabel("端口"));
north.add(txt_port);//在JPanel组件中添加端口组件
north.add(new JLabel("服务器IP:"));
north.add(txt_Ip);//在JPanel组件中添加IP组件
north.add(new JLabel("姓名:"));
north.add(txt_name);//添加文本域组件
north.add(button_start);//添加按钮组件
north.add(button_stop);//添加按钮组件
north.setBorder(new TitledBorder("连接信息"));
rightScroll = new JScrollPane(textArea);
rightScroll.setBorder(new TitledBorder("聊天记录区"));
leftScroll = new JScrollPane(userList);
leftScroll.setBorder(new TitledBorder("在线用户明细"));//设置组件的边框
south = new JPanel(new BorderLayout());
south.add(textField, "Center");
south.add(button_send, "East");
south.setBorder(new TitledBorder("写消息"));
centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll,rightScroll);
centerSplit.setDividerLocation(100);//设置分隔条的相对位置
frame = new JFrame("客户端");
frame.add(north, "North");
frame.add(centerSplit, "Center");
frame.add(south, "South");
frame.setSize(750, 350);
int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;//获取屏幕的宽度
int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;//获取屏幕的高度
frame.setLocation((screen_width - frame.getWidth()) / 2,(screen_height - frame.getHeight()) / 2);//设置窗口的相对位置
frame.setVisible(true);//设置组件可见
// 写消息的文本框中按回车键时事件
textField.addActionListener(new ActionListener() {//添加监听,监听文本域消息
public void actionPerformed(ActionEvent arg0) {
send();
}
});
// 单击发送按钮时事件
button_send.addActionListener(new ActionListener() {//添加监听,监听发送按钮消息
public void actionPerformed(ActionEvent e) {
send();
}
});
// 单击连接按钮时事件
button_start.addActionListener(new ActionListener() {//添加监听,监听连接按钮消息
public void actionPerformed(ActionEvent e) {
int port;
if (crossFire) {
JOptionPane.showMessageDialog(frame, "WARNING! 重复链接","错误", JOptionPane.ERROR_MESSAGE);
return;
}
try {
try {
port = Integer.parseInt(txt_port.getText().trim());
} catch (NumberFormatException e2) {
throw new Exception("端口号错误! 端口应为整数!");
}
String hostIp = txt_Ip.getText().trim();
String name = txt_name.getText().trim();
if (name.equals("")) {
throw new Exception("姓名不能为空!");
}
if(hostIp.equals(""))
throw new Exception("服务器IP不能为空!");
boolean flag = connectServer(port, hostIp, name);
if (flag == false) {
throw new Exception("无连接,或连接失败!");
}
frame.setTitle(name);
JOptionPane.showMessageDialog(frame, "成功连接!");
} catch (Exception exc) {
JOptionPane.showMessageDialog(frame, exc.getMessage(),"错误", JOptionPane.ERROR_MESSAGE);
}
}
});
// 单击断开按钮时事件
button_stop.addActionListener(new ActionListener() {//添加监听,监听断开按钮消息
public void actionPerformed(ActionEvent e) {
if (!crossFire) {
JOptionPane.showMessageDialog(frame, "Warning!重复连接","错误", JOptionPane.ERROR_MESSAGE);
return;
}
try {
boolean flag = closeConnection();// 断开连接
if (flag == false) {
throw new Exception("断开连接发生异常!");
}
JOptionPane.showMessageDialog(frame, "已断开!");
} catch (Exception exc) {
JOptionPane.showMessageDialog(frame, exc.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
});
// 关闭窗口时事件
frame.addWindowListener(new WindowAdapter() {//添加窗口监听
public void windowClosing(WindowEvent e) {
if (crossFire) {
closeConnection();//关闭连接
}
System.exit(0);//退出程序
}
});
}
public boolean connectServer(int port, String hostIp, String name) {//连接服务器
try {
socket = new Socket(hostIp, port);// 根据端口号和服务器Ip建立连接
writer = new PrintWriter(socket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sendMessage(name + "@" + socket.getLocalAddress().toString()); //发送客户端用户基本信息(用户名和ip地址)
messageThread = new MessageThread(reader, textArea);//开启接收消息的线程
messageThread.start();
crossFire = true;//已经连接上了
return true;
} catch (Exception e) {
textArea.append("与端口号为:" + port + " IP地址为:" + hostIp+ " 的服务器连接失败!" + "\r\n");
crossFire = false;//未连接上
return false;
}
}
public void sendMessage(String message) {
writer.println(message);
writer.flush();
}
@SuppressWarnings("deprecation")
public synchronized boolean closeConnection() {//同步方法
try {
sendMessage("CLOSE");//发送断开连接命令给服务器
messageThread.stop();//停止接受消息线程
reader.close();//释放资源
writer.close();
socket.close();
crossFire=false;
return true;
} catch (IOException e1) {
e1.printStackTrace();
crossFire = true;
return false;
}
}
class MessageThread extends Thread {//接收消息线程
private BufferedReader reader;
private JTextArea textArea;
public MessageThread(BufferedReader reader, JTextArea textArea) {//创建线程的构造方法
this.reader = reader;
this.textArea = textArea;
}
public synchronized void closeCon() throws Exception {//同步方法
listModel.removeAllElements();// 清空用户列表
reader.close();//关闭连接释放资源
writer.close();
socket.close();
crossFire = false;//修改状态为断开
}
@SuppressWarnings("unlikely-arg-type")
public void run() {
String message = "";
while (true) {
try {
message = reader.readLine();
StringTokenizer stringTokenizer = new StringTokenizer(message, "/@");//分解字符串
String command = stringTokenizer.nextToken();//返回下一个
if (command.equals("CLOSE")){// 服务器已关闭命令
textArea.append("服务器已关闭!\r\n");
closeCon();//关闭连接
return;//结束线程
} else if (command.equals("ADD")) {//有用户上线更新在线列表
String username;
String userIp;
if ((username = stringTokenizer.nextToken()) != null&& (userIp = stringTokenizer.nextToken()) != null) {
User user = new User(username, userIp);
onLineUsers.put(username, user);
listModel.addElement(username);
}
} else if (command.equals("DELETE")) {//有用户下线更新在线列表
String username = stringTokenizer.nextToken();
User user = (User) onLineUsers.get(username);
onLineUsers.remove(user);//删除下线用户名及ip
listModel.removeElement(username);//删除在线列表中用户名
} else if (command.equals("USERLIST")) {// 加载在线用户列表
int size = Integer.parseInt(stringTokenizer.nextToken());//使用下一个参数指定的基数,将字符串参数解析为有符号的整数
String username = null;
String userIp = null;
for (int i = 0; i < size; i++) {
username = stringTokenizer.nextToken();
userIp = stringTokenizer.nextToken();
User user = new User(username, userIp);
onLineUsers.put(username, user);//更新在线用户
listModel.addElement(username);//添加用户名
}
} else if (command.equals("MAX")) {//人数达到上限
textArea.append(stringTokenizer.nextToken()+ stringTokenizer.nextToken() + "\r\n");//将用户名及用户IP添加到文本域,提示用户达到上限
closeCon();//关闭连接
JOptionPane.showMessageDialog(frame, "服务器缓冲区已满!", "错误",JOptionPane.ERROR_MESSAGE);//消息对话框
return;// 结束线程
} else {//消息
textArea.append(message + "\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new Client();
}
}
服务器代码如下:
Sever.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
public class Sever {
JFrame frame;
JTextArea contentArea; //文本域
JTextField txt_message,txt_max,txt_port; //用于显示文本信息,设置最大连接人数,设置端口号
JButton button_start,button_stop ,button_send;//启动按钮,停止按钮,发送按钮
JPanel north,south; //上面面板,下面面板
JScrollPane right,left; //左边滚动面板,右边滚动面板
JSplitPane centerSplit; //分割面板
JList<String> userList; //列表组件
DefaultListModel<String> listModel;//点击事件
ServerSocket serverSocket;//创建套接字
ServerThread serverThread;//创建线程
private ArrayList<ClientThread> clients;//创建客户端的集合
private boolean Fire = false;//创建一个布尔值
public void send() {//创建一个发送消息的方法send
if (!Fire) {//判断是是否启动服务器
JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",JOptionPane.ERROR_MESSAGE);//类提示框
return;
}
if (clients.size() == 0) {
JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",JOptionPane.ERROR_MESSAGE);//判断是否有用户在线
return;
}
String message = txt_message.getText().trim();//文本框内容获取
if (message == null || message.equals("")) {JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",JOptionPane.ERROR_MESSAGE);//判断消息框是否有文字
return;
}
sendServerMessage(message);// 群发服务器消息(调用sendServerMessage方法)
contentArea.append("服务器:" + txt_message.getText() + "\r\n");//在文本域添加服务器发送的新内容
txt_message.setText(null);
}
public Sever() {//创建构造函数
frame = new JFrame("服务器");//实例化一个服务器窗体对象
contentArea = new JTextArea();//实例化文本域
contentArea.setEditable(false);//设置文本为不可读状态
contentArea.setForeground(Color.red);//设置背景颜色为红色
txt_message = new JTextField();//消息编辑
txt_max = new JTextField();//设置允许连接的最多人数
txt_port = new JTextField();//设置端口号
button_start = new JButton("启动");//创建启动按钮
button_stop = new JButton("停止");//创建停止按钮
button_send = new JButton("发送");//创建发送按钮
button_stop.setEnabled(false);//设置按钮不可用
listModel = new DefaultListModel<String>();//实例化鼠标点击
userList = new JList<String>(listModel);//实例化列表框对象
south = new JPanel(new BorderLayout());//实例化下面面板
south.setBorder(new TitledBorder("写消息"));//文本按钮
south.add(txt_message, "Center");//添加文本
south.add(button_send, "East");//发送文本
left = new JScrollPane(userList);//实例化左边滚动条,传入用户的名字
left.setBorder(new TitledBorder("在线用户明细"));
right = new JScrollPane(contentArea);//实例化右边滚动条,传入文本域
right.setBorder(new TitledBorder("聊天记录区"));//添加滚动面板内容
centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left,right);//实例化分割线 将面板分割成左右两部分
centerSplit.setDividerLocation(100);//设置centerSplit的分隔线的相对位置
north = new JPanel();//实例化上面面板
north.setLayout(new GridLayout(1, 4));//窗口布局
north.add(new JLabel("人数上限"));//JButton实例添加到JPanel中
north.add(txt_max);//JButton实例添加到JPanel中
north.add(new JLabel("端口"));//JButton实例添加到JPanel中
north.add(txt_port);//JButton实例添加到JPanel中
north.add(button_start);//JButton实例添加到JPanel中
north.add(button_stop);//JButton实例添加到JPanel中
north.setBorder(new TitledBorder("配置信息"));
frame.setLayout(new BorderLayout());//容器使用绝对布局
frame.add(north, "North");//添加上面板组件
frame.add(centerSplit, "Center");//添加分割线组件
frame.add(south, "South");//条件下面板组件
frame.setSize(750, 350);//设置组件的宽和高
int s_width=Toolkit.getDefaultToolkit().getScreenSize().width;//获取电脑屏幕的宽
int s_height=Toolkit.getDefaultToolkit().getScreenSize().height;//获取电脑屏幕的高
frame.setLocation((s_width - frame.getWidth()) / 2,(s_height - frame.getHeight()) / 2);//设置组件左上角的坐标,将其放在屏幕中间
frame.setVisible(true);//设置窗体可见
frame.addWindowListener(new WindowAdapter() {//添加窗体监听事件
public void windowClosing(WindowEvent e) {// 窗口关闭时触发
if (Fire) {
closeServer();// 关闭服务器
}
System.exit(0);// 退出程序
}
});
txt_message.addActionListener(new ActionListener() {//添加监听,监听文本框按回车键按钮事件
public void actionPerformed(ActionEvent e) {
send();
}
});
button_send.addActionListener(new ActionListener() {//添加监听,监听发送按钮事件
public void actionPerformed(ActionEvent arg0) {
send();
}
});
button_start.addActionListener(new ActionListener() {//添加监听,监听启动服务器按钮时事件
public void actionPerformed(ActionEvent e) {
if (Fire) {
JOptionPane.showMessageDialog(frame, "Warning!重复启动","错误", JOptionPane.ERROR_MESSAGE);
return;
}
int max = 0;//最大人数
int port = 0;//端口号
try {
try {
max = Integer.parseInt(txt_max.getText());
} catch (Exception e1) {
throw new Exception("人数上限不能为空");
}
if (max <= 0) {
throw new Exception("人数上限应为正整数!");
}
try {
port = Integer.parseInt(txt_port.getText());
} catch (Exception e1) {
throw new Exception("端口号应为整数!");
}
if (port <= 0) {
throw new Exception("端口号应为正整数!");
}
serverStart(max, port);
contentArea.append("服务器已成功启动!人数上限:" + max + ",端口:" + port+ "\r\n");
JOptionPane.showMessageDialog(frame, "服务器成功启动!");
button_start.setEnabled(false);//设置按钮不可用
txt_max.setEnabled(true);
txt_port.setEnabled(true);
button_stop.setEnabled(true);//设置按钮可用
} catch (Exception exc) {
JOptionPane.showMessageDialog(frame, exc.getMessage(),"错误", JOptionPane.ERROR_MESSAGE);
}
}
});
// 单击停止服务器按钮时事件
button_stop.addActionListener(new ActionListener() {//添加监听停止按钮时间
public void actionPerformed(ActionEvent e) {
if (!Fire) {
JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",JOptionPane.ERROR_MESSAGE);
return;
}
try {
closeServer();
button_start.setEnabled(true);
txt_max.setEnabled(true);
txt_port.setEnabled(true);
button_stop.setEnabled(false);
contentArea.append("服务器成功停止!\r\n");
JOptionPane.showMessageDialog(frame, "服务器成功停止!");
} catch (Exception exc) {
JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",JOptionPane.ERROR_MESSAGE);
}
}
});
}
// 启动服务器
public void serverStart(int max, int port) throws java.net.BindException {
try {
clients = new ArrayList<ClientThread>();//创建一个客户端集合
serverSocket = new ServerSocket(port);//套接字创建
serverThread = new ServerThread(serverSocket, max);//实例化线程
serverThread.start();//启动线程
Fire = true;
} catch (BindException e) {
Fire = false;
throw new BindException("端口号已被占用,请更换!");
} catch (Exception e1) {
e1.printStackTrace();
Fire = false;
throw new BindException("启动服务器异常!");
}
}
@SuppressWarnings("deprecation")
public void closeServer() { //关闭服务器方法
try {
if (serverThread != null)
serverThread.stop();//关闭线程
for (int i = clients.size() - 1; i >= 0; i--) {//创建for循环设置i的初始值位客户端数值减一
// 给所有在线用户发送关闭命令
clients.get(i).getWriter().println("CLOSE");
clients.get(i).getWriter().flush();
// 释放资源
clients.get(i).stop();// 停止此条为客户端服务的线程
clients.get(i).reader.close();
clients.get(i).writer.close();
clients.get(i).socket.close();
clients.remove(i);
}
if (serverSocket != null) {
serverSocket.close();//关闭服务器端连接
}
listModel.removeAllElements();//清空用户列表
Fire = false;
} catch (IOException e) {
e.printStackTrace();
Fire = true;
}
}
public void sendServerMessage(String message) {// 群发服务器消息
for (int i = clients.size() - 1; i >= 0; i--) {
clients.get(i).getWriter().println("服务器:" + message + "(多人发送)");
clients.get(i).getWriter().flush();
}
}
class ServerThread extends Thread {//服务器线程
private ServerSocket serverSocket;
private int max;//人数上限
public ServerThread(ServerSocket serverSocket, int max) {//服务器线程的构造方法
this.serverSocket = serverSocket;
this.max = max;
}
public void run() {//重写run方法
while (true) {//不停的等待客户端的链接
try {
Socket socket = serverSocket.accept();//服务器套接字开启监听,返回Socket,抛出异常
if (clients.size() == max) {// 如果已达人数上限
BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));//将字节流转化成字符流,字节流的来源(套接字socket)
PrintWriter w = new PrintWriter(socket.getOutputStream());//将传进来的值写入
// 接收客户端的基本用户信息
String inf = r.readLine();
StringTokenizer st = new StringTokenizer(inf, "@");
User user = new User(st.nextToken(), st.nextToken());//获取用户名和IP地址
// 反馈连接成功信息
w.println("服务器:对不起," + user.getName()+ user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");
w.flush();//将传进来的值写入
r.close();// 释放资源
w.close();
socket.close();
continue;
}
ClientThread client = new ClientThread(socket);
client.start();//开启对此客户端服务的线程
clients.add(client);
listModel.addElement(client.getUser().getName());//更新在线列表
contentArea.append(client.getUser().getName()+ client.getUser().getIp() + "上线!\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ClientThread extends Thread {//为一个客户端服务的线程
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
private User user;
//get方法
public BufferedReader getReader() {
return reader;
}
public PrintWriter getWriter() {
return writer;
}
public User getUser() {
return user;
}
public ClientThread(Socket socket) {//客户端线程的构造方法
try {
this.socket = socket;
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//将字节流转化成字符流,字节流的来源(套接字socket)
writer = new PrintWriter(socket.getOutputStream());
// 接收客户端的基本用户信息
String inf = reader.readLine();//读取客户端字符串
StringTokenizer st = new StringTokenizer(inf, "@");
user = new User(st.nextToken(), st.nextToken());
// 反馈连接成功信息
writer.println(user.getName() + user.getIp() + "与服务器连接成功!");
writer.flush();
// 反馈当前在线用户信息
if (clients.size() > 0) {
String temp = "";
for (int i = clients.size() - 1; i >= 0; i--) {
temp += (clients.get(i).getUser().getName() + "/" + clients.get(i).getUser().getIp())+ "@";
}
writer.println("USERLIST@" + clients.size() + "@" + temp);
writer.flush();
}
// 向所有在线用户发送该用户上线命令
for (int i = clients.size() - 1; i >= 0; i--) {
clients.get(i).getWriter().println("ADD@" + user.getName() + user.getIp());
clients.get(i).getWriter().flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public void run() {//不断接收客户端的消息,进行处理。重写run方法
String message = null;
while (true) {
try {
message = reader.readLine();//接收客户端消息
if (message.equals("CLOSE"))//下线命令
{
contentArea.append(this.getUser().getName()+ this.getUser().getIp() + "下线!\r\n");
reader.close();
writer.close();
socket.close();
//向所有在线用户发送该用户的下线命令
for (int i = clients.size() - 1; i >= 0; i--) {
clients.get(i).getWriter().println( user.getName());clients.get(i).getWriter().flush();
}
listModel.removeElement(user.getName());//更新在线列表
//删除此条客户端服务线程
for (int i = clients.size() - 1; i >= 0; i--) {
if (clients.get(i).getUser() == user) {
ClientThread temp = clients.get(i);
clients.remove(i);//删除此用户的服务线程
temp.stop();//停止这条服务线程
return;
}
}
} else {
dispatcherMessage(message);//转发消息
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 转发消息
public void dispatcherMessage(String message) {
StringTokenizer stringTokenizer = new StringTokenizer(message, "@");
String source = stringTokenizer.nextToken();
String owner = stringTokenizer.nextToken();
String content = stringTokenizer.nextToken();
message = source + ":" + content;
contentArea.append(message + "\r\n");
if (owner.equals("ALL")) {// 群发
for (int i = clients.size() - 1; i >= 0; i--) {
clients.get(i).getWriter().println(message + "(多人发送)");
clients.get(i).getWriter().flush();
}
}
}
}
public static void main(String[] args) {
new Sever();//实例化
}
}
user类如下:
User.java
public class User{
private String name;
private String ip;
//构造函数
public User(String name, String ip) {
this.name = name;
this.ip = ip;
}
//get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}