本文实例为大家分享了Java实现简单聊天室功能的具体代码,供大家参考,具体内容如下
一、客户端的创建
1.我们可以用Socket来创建客户端
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("-----Client1-----");
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String name =br.readLine();
//1、建立连接: 使用Socket创建客户端 +服务的地址和端口
Socket client =new Socket("localhost",8888);
//2、客户端发送消息
new Thread(new Send(client,name)).start();
new Thread(new Receive(client)).start();
}
}
2.这时我们需要接受其他客户端发送的数据,我们需要创建一个客户端的接收方法和发送方法,我可以用阻塞式的方式进行接收和发送,考虑到多线程的安全性,可以实现Runnable
1.Send发送端:
public class Send implements Runnable {
private BufferedReader console ;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;
public Send(Socket client,String name) {
this.client =client;
console =new BufferedReader(new InputStreamReader(System.in));
this.isRunning = true;
this.name = name;
try {
dos =new DataOutputStream(client.getOutputStream());
//发送名称
send(name);
} catch (IOException e) {
System.out.println("==1==");
this.release();
}
}
@Override
public void run() {
while(isRunning) {
String msg = getStrFromConsole();
if(!msg.equals("")) {
send(msg);
}
}
}
//发送消息
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println(e);
System.out.println("===3==");
release();
}
}
private String getStrFromConsole() {
try {
return console.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
//释放资源
private void release() {
this.isRunning = false;
CloseUtils.close(dos,client);
}
}
2.接收端
public class Receive implements Runnable {
private DataInputStream dis ;
private Socket client;
private boolean isRunning;
public Receive(Socket client) {
this.client = client;
this.isRunning = true;
try {
dis =new DataInputStream(client.getInputStream());
} catch (IOException e) {
System.out.println("====离开一位=====");
release();
}
}
//接收消息
private String receive() {
String msg ="";
try {
msg =dis.readUTF();
} catch (IOException e) {
System.out.println("====接收消息异常====");
release();
}
return msg;
}
@Override
public void run() {
while(isRunning) {
String msg =receive();
if(!msg.equals("")) {
System.out.println(msg);
}
}
}
//释放资源
private void release() {
this.isRunning = false;
CloseUtils.close(dis,client);
}
}
3.统一释放资源的方法可以提出,服务的也用得上
public class CloseUtils {
public static void close(Closeable... targets ) {
for(Closeable target:targets) {
try {
if(null!=target) {
target.close();
}
}catch(Exception e) {
}
}
}
}
二、客户端的创建
服务端用ServerSocket创建,如果我们吧服务的和客户端看成事一个通信通道(Channel),那么每个客户端的接入都会创建一个通信通道,那么通信通道的创建也需要实现多线程,可以实现Runnable接口,我们存放通道可以用线程容器CopyOnWriteArrayList来存放通道。
public class Chat {
private static CopyOnWriteArrayList<Channel> all =new CopyOnWriteArrayList<Channel>();
public static void main(String[] args) throws IOException {
System.out.println("-----Server-----");
// 1、指定端口 使用ServerSocket创建服务器
ServerSocket server =new ServerSocket(8888);
// 2、阻塞式等待连接 accept
while(true) {
Socket client =server.accept();
System.out.println("一个客户端建立了连接");
Channel c =new Channel(client);
all.add(c); //管理所有的成员
new Thread(c).start();
}
}
//一个客户代表一个Channel
static class Channel implements Runnable{
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos =new DataOutputStream(client.getOutputStream());
isRunning =true;
//获取名称
this.name =receive();//退出出聊天室
//欢迎你的到来
this.send("欢迎你的到来");
sendOthers(this.name+"来了徐康聊天室",true);//暂时固定为私聊
} catch (IOException e) {
System.out.println("---1------");
release();
}
}
//接收消息
private String receive() {
String msg ="";
try {
msg =dis.readUTF();
} catch (IOException e) {
System.out.println("---2------");
release();
}
return msg;
}
//发送消息
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("---3------");
release();
}
}
private void sendOthers(String msg,boolean isSys) {
boolean isPrivate = msg.startsWith("@");
if(isPrivate) { //私聊
int idx =msg.indexOf(":");
//获取目标和数据
String targetName = msg.substring(1,idx);
msg = msg.substring(idx+1);
for(Channel other: all) {
if(other.name.equals(targetName)) {//目标
other.send(this.name +"悄悄地对您说:"+msg);
break;
}
}
}else {
for(Channel other: all) {
if(other==this) { //自己
continue;
}
if(!isSys) {
other.send(this.name +"对所有人说:"+msg);//群聊消息
}else {
other.send(msg); //系统消息
}
}
}
}
//释放资源
private void release() {
this.isRunning = false;
CloseUtils.close(dis,dos,client);
//退出
all.remove(this);
sendOthers(this.name+"离开大家庭...",true);
}
@Override
public void run() {
while(isRunning) {
String msg = receive() ;
if(!msg.equals("")) {
//send(msg);
sendOthers(msg,false);
}
}
}
}
}
三、效果如下
1.启动服务端
2.启动客户端
3.发送消息
总结
此案例只能用来打发时间,入门网络编程可以参考一下,真正的开发不会这么弄。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。