java局域网聊天小程序
这篇文章主要为大家详细介绍了java局域网聊天小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下本文实例为大家分享了java局域网聊天程序的具体代码,供大家参考,具体内容如下
有服务器端 和客户端两个界面,运行需要加上自己的ip地址,端口可以随意,但是客户端端口,和服务器端口要一样,然后就可以几个人一块聊天了
简单贴几个代码吧
client.java客户端代码
package chat;
import java.awt.borderlayout;//布置容器的边框布局
import java.awt.color;
import java.awt.container;
import java.awt.gridlayout;//布局处理器
import java.awt.toolkit;//抽象超类
import java.awt.event.actionevent;//指示发生了组件定义的动作的语义事件
import java.awt.event.actionlistener;//用于接收操作事件的侦听器接口
import java.awt.event.mouseevent;//指示组件中发生鼠标动作的事件
import java.awt.event.mouselistener;//鼠标事件的侦听器接口
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;// hashmap 是 map 接口的常用实现类
import java.util.map;//存数据,将键映射到值的对象
import java.util.stringtokenizer;//允许应用程序将字符串分解为标记
import javax.swing.borderfactory;//创建一个浮雕式的边框
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.emptyborder;//一个占用空间但不执行绘制的空透明边框
import javax.swing.border.titledborder;//该类实现在指定位置以指定对齐方式显示字符串标题的任意边框
import oldchat.chatframe;
public class client
{
private jframe frame;
private jlist userlist;
private jtextarea textarea;
private jtextfield textfield;
private jtextfield txt_port;
private jtextfield txt_hostip;
private jtextfield txt_name;
private jbutton btn_start;
private jbutton btn_stop;
private jbutton btn_send;
private jpanel northpanel;
private jpanel southpanel;
private jscrollpane rightscroll;
private jscrollpane leftscroll;
private jsplitpane centersplit;
private defaultlistmodel listmodel;
private boolean isconnected = false;
private socket socket;//创建套接字
private printwriter writer;
private bufferedreader reader;
private messagethread messagethread;// 负责接收消息的线程
private map<string, user> onlineusers = new hashmap<string, user>();// 所有在线用户
// 主方法,程序入口
public static void main(string[] args)
{
new client();
}
// 执行发送
public void send()
{
if (!isconnected)
{
joptionpane.showmessagedialog(frame, "还没有连接服务器,无法发送消息!", "错误",
joptionpane.error_message);
return;
}
string message = textfield.gettext().trim();
if (message == null || message.equals(""))
{
joptionpane.showmessagedialog(frame, "消息不能为空!", "错误",
joptionpane.error_message);
return;
}
sendmessage(frame.gettitle() + "@" + "all" + "@" + message);
textfield.settext(null);
}
// 构造方法
public client()
{
textarea = new jtextarea();
textarea.seteditable(false);
textarea.setforeground(color.blue);
textfield = new jtextfield();
txt_port = new jtextfield("6666");
txt_hostip = new jtextfield();
txt_name = new jtextfield();
btn_start = new jbutton("连接");
btn_stop = new jbutton("断开");
btn_send = new jbutton("发送");
listmodel = new defaultlistmodel();
userlist = new jlist(listmodel);
northpanel = new jpanel();
northpanel.setlayout(new gridlayout(1, 7));
northpanel.add(new jlabel("端口"));
northpanel.add(txt_port);
northpanel.add(new jlabel("服务器ip"));
northpanel.add(txt_hostip);
northpanel.add(new jlabel("姓名"));
northpanel.add(txt_name);
northpanel.add(btn_start);
northpanel.add(btn_stop);
northpanel.setborder(new titledborder("连接信息"));
rightscroll = new jscrollpane(textarea);
rightscroll.setborder(new titledborder("群聊消息显示区"));
leftscroll = new jscrollpane(userlist);
leftscroll.setborder(new titledborder("在线用户(双击私聊)"));
southpanel = new jpanel(new borderlayout());
southpanel.add(textfield, "center");
southpanel.add(btn_send, "east");
southpanel.setborder(new titledborder("写消息"));
centersplit = new jsplitpane(jsplitpane.horizontal_split, leftscroll,
rightscroll);
centersplit.setdividerlocation(100);
frame = new jframe("客户端");
// 更改jframe的图标:
//frame.seticonimage(toolkit.getdefaulttoolkit().createimage(client.class.getresource("qq.jpg")));
frame.setlayout(new borderlayout());
frame.add(northpanel, "north");
frame.add(centersplit, "center");
frame.add(southpanel, "south");
frame.setsize(600, 400);
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();
}
});
// 单击发送按钮时事件
btn_send.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent e)
{
send();
}
});
// 单击连接按钮时事件
btn_start.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent e)
{
int port;
if (isconnected) {
joptionpane.showmessagedialog(frame, "已处于连接上状态,不要重复连接!",
"错误", joptionpane.error_message);
return;
}
try {
try {
port = integer.parseint(txt_port.gettext().trim());
} catch (numberformatexception e2) {
throw new exception("端口号不符合要求!端口为整数!");
}
string hostip = txt_hostip.gettext().trim();
string name = txt_name.gettext().trim();
if (name.equals("") || 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);
}
}
});
//双击聊天(私聊)
userlist.addmouselistener(new mouselistener()
{
public void mousereleased(mouseevent e) {}
public void mousepressed(mouseevent e) {}
public void mouseexited(mouseevent e) {}
public void mouseentered(mouseevent e) {}
public void mouseclicked(mouseevent e)
{
if(e.getclickcount()==2)
{
user user=onlineusers.get(userlist.getselectedvalue());
chatframe.main(user.getip());;
}
}
});
// 单击断开按钮时事件
btn_stop.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent e)
{
if (!isconnected) {
joptionpane.showmessagedialog(frame, "已处于断开状态,不要重复断开!",
"错误", 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 (isconnected) {
closeconnection();// 关闭连接
}
system.exit(0);// 退出程序
}
});
}
/**
* 连接服务器
*
* @param port
* @param hostip
* @param name
*/
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()));
// 发送客户端用户基本信息(用户名和ip地址)
sendmessage(name + "@" + socket.getlocaladdress().tostring());
// 开启接收消息的线程
messagethread = new messagethread(reader, textarea);
messagethread.start();
isconnected = true;// 已经连接上了
return true;
} catch (exception e) {
textarea.append("与端口号为:" + port + "ip地址为:" + hostip
+ "的服务器连接失败!" + "\r\n");
isconnected = false;// 未连接上
return false;
}
}
/**
* 发送消息
*
* @param message
*/
public void sendmessage(string message)
{
writer.println(message);
writer.flush();
}
/**
* 客户端主动关闭连接
*/
@suppresswarnings("deprecation")
public synchronized boolean closeconnection()
{
try {
sendmessage("close");// 发送断开连接命令给服务器
messagethread.stop();// 停止接受消息线程
// 释放资源
if (reader != null) {
reader.close();
}
if (writer != null) {
writer.close();
}
if (socket != null) {
socket.close();
}
isconnected = false;
return true;
} catch (ioexception e1) {
e1.printstacktrace();
isconnected = 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();
// 被动的关闭连接释放资源
if (reader != null) {
reader.close();
}
if (writer != null) {
writer.close();
}
if (socket != null) {
socket.close();
}
isconnected = false;// 修改状态为断开
}
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);
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");
closecon();// 被动的关闭连接
joptionpane.showmessagedialog(frame, "服务器缓冲区已满!", "错误",
joptionpane.error_message);
return;// 结束线程
} else {// 普通消息
textarea.append(message + "\r\n");
}
} catch (ioexception e) {
e.printstacktrace();
} catch (exception e) {
e.printstacktrace();
}
}
}
}
}
server.java
package chat;
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 server
{
private jframe frame;
private jtextarea contentarea;
private jtextfield txt_message;
private jtextfield txt_max;
private jtextfield txt_port;
private jbutton btn_start;
private jbutton btn_stop;
private jbutton btn_send;
private jpanel northpanel;
private jpanel southpanel;
private jscrollpane rightpanel;
private jscrollpane leftpanel;
private jsplitpane centersplit;
private jlist userlist;
private defaultlistmodel listmodel;
private serversocket serversocket;
private serverthread serverthread;
private arraylist<clientthread> clients;
private boolean isstart = false;
// 主方法,程序执行入口
public static void main(string[] args)
{
new server();
}
// 执行消息发送
public void send()
{
if (!isstart)
{
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);// 群发服务器消息
contentarea.append("服务器说:" + txt_message.gettext() + "\r\n");
txt_message.settext(null);
}
// 构造放法
public server()
{
frame = new jframe("服务器");
// 更改jframe的图标:
//frame.seticonimage(toolkit.getdefaulttoolkit().createimage(client.class.getresource("qq.png")));
//frame.seticonimage(toolkit.getdefaulttoolkit().createimage(server.class.getresource("qq.jpg")));
contentarea = new jtextarea();
contentarea.seteditable(false);
contentarea.setforeground(color.blue);
txt_message = new jtextfield();
txt_max = new jtextfield("30");
txt_port = new jtextfield("6666");
btn_start = new jbutton("启动");
btn_stop = new jbutton("停止");
btn_send = new jbutton("发送");
btn_stop.setenabled(false);
listmodel = new defaultlistmodel();
userlist = new jlist(listmodel);
southpanel = new jpanel(new borderlayout());
southpanel.setborder(new titledborder("写消息"));
southpanel.add(txt_message, "center");
southpanel.add(btn_send, "east");
leftpanel = new jscrollpane(userlist);
leftpanel.setborder(new titledborder("在线用户"));
rightpanel = new jscrollpane(contentarea);
rightpanel.setborder(new titledborder("群聊消息显示区"));
centersplit = new jsplitpane(jsplitpane.horizontal_split, leftpanel,
rightpanel);
centersplit.setdividerlocation(100);
northpanel = new jpanel();
northpanel.setlayout(new gridlayout(1, 6));
northpanel.add(new jlabel("人数上限"));
northpanel.add(txt_max);
northpanel.add(new jlabel("端口"));
northpanel.add(txt_port);
northpanel.add(btn_start);
northpanel.add(btn_stop);
northpanel.setborder(new titledborder("配置信息"));
frame.setlayout(new borderlayout());
frame.add(northpanel, "north");
frame.add(centersplit, "center");
frame.add(southpanel, "south");
frame.setsize(600, 400);
//frame.setsize(toolkit.getdefaulttoolkit().getscreensize());//设置全屏
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);
// 关闭窗口时事件
frame.addwindowlistener(new windowadapter()
{
public void windowclosing(windowevent e)
{
if (isstart) {
closeserver();// 关闭服务器
}
system.exit(0);// 退出程序
}
});
// 文本框按回车键时事件
txt_message.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent e)
{
send();
}
});
// 单击发送按钮时事件
btn_send.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent arg0)
{
send();
}
});
// 单击启动服务器按钮时事件
btn_start.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent e)
{
if (isstart) {
joptionpane.showmessagedialog(frame, "服务器已处于启动状态,不要重复启动!",
"错误", joptionpane.error_message);
return;
}
int max;
int port;
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, "服务器成功启动!");
btn_start.setenabled(false);
txt_max.setenabled(false);
txt_port.setenabled(false);
btn_stop.setenabled(true);
} catch (exception exc) {
joptionpane.showmessagedialog(frame, exc.getmessage(),
"错误", joptionpane.error_message);
}
}
});
// 单击停止服务器按钮时事件
btn_stop.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent e)
{
if (!isstart) {
joptionpane.showmessagedialog(frame, "服务器还未启动,无需停止!", "错误",
joptionpane.error_message);
return;
}
try {
closeserver();
btn_start.setenabled(true);
txt_max.setenabled(true);
txt_port.setenabled(true);
btn_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();
isstart = true;
} catch (bindexception e) {
isstart = false;
throw new bindexception("端口号已被占用,请换一个!");
} catch (exception e1) {
e1.printstacktrace();
isstart = false;
throw new bindexception("启动服务器异常!");
}
}
// 关闭服务器
@suppresswarnings("deprecation")
public void closeserver() {
try {
if (serverthread != null)
serverthread.stop();// 停止服务器线程
for (int i = clients.size() - 1; i >= 0; 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();// 清空用户列表
isstart = false;
} catch (ioexception e) {
e.printstacktrace();
isstart = 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() {
while (true) {// 不停的等待客户端的链接
try {
socket socket = serversocket.accept();
if (clients.size() == max) {// 如果已达人数上限
bufferedreader r = new bufferedreader(
new inputstreamreader(socket.getinputstream()));
printwriter w = new printwriter(socket
.getoutputstream());
// 接收客户端的基本用户信息
string inf = r.readline();
stringtokenizer st = new stringtokenizer(inf, "@");
user user = new user(st.nexttoken(), st.nexttoken());
// 反馈连接成功信息
w.println("max@服务器:对不起," + 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;
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()));
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() {// 不断接收客户端的消息,进行处理。
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(
"delete@" + 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();
}
}
}
}
}
运行截图
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CodeAE代码之家。
原文链接:https://blog.csdn.net/zhupengqq/article/details/78429089
http://www.zzvips.com/article/173889.html
页:
[1]