java群聊tcp_java 网络编程-TCP-多人群聊究极版

客户端:

多个客户可以正常收发信息,因为可以同时发送和接受信息,不是发送完信息后等待

返回信息,所以要加入多线程

public class Client {

public static void main(String[]args) throws UnknownHostException, IOException

{

System.out.println("客户端启动中...");

BufferedReader br =new BufferedReader(new InputStreamReader(System.in));

System.out.println("请输入用户名:");

String name=br.readLine();

Socket client =new Socket("localhost",9999);

new Thread(new Send(client,name)).start();//在线程还没启动之前,通过构造方法发送名称,先于信息的发送,

//因为接收信息时,名称已经发送并被读取到变量中

new Thread(new Receive(client)).start();

}

}

作为释放资源工具类

public class utils {

public static void close(Closeable... target )

{

for(Closeable it:target)

{

try {

if(null!=it)

{

it.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

客户端的发送端封装了:

发送消息

从键盘读取消息

run()

释放资源

public class Send implements Runnable{

private BufferedReader br;

private DataOutputStream dos;

private Socket client;

private boolean flag=true;

private String name;

public Send(Socket client,String name)

{

this.client=client;

this.name=name;

br=new BufferedReader(new InputStreamReader(System.in));

try {

dos=new DataOutputStream(client.getOutputStream());

//发送名称

send(name);

} catch (IOException e) {

this.release();

}

}

public void run()

{

while(flag)

{

String msg=getstr();

send(msg);

}

}

private void release()

{

this.flag=false;

utils.close(dos,client);

}

//从控制台获取消息

private String getstr()

{

try {

String msg=br.readLine();

return msg;

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

private void send(String msg)

{

try {

dos.writeUTF(msg);

dos.flush();

} catch (IOException e) {

release();

}

}

}

客户端的接收端封装了:

接收消息

run()

释放资源

public class Receive implements Runnable {

private DataInputStream dis;

private Socket client;

private boolean flag=true;

public Receive(Socket client)

{

this.client=client;

try {

dis=new DataInputStream(client.getInputStream());

} catch (IOException e) {

release();

}

}

private String receive()

{

String msg;

try {

msg = dis.readUTF();

return msg;

} catch (IOException e) {

release();

}

return null;

}

public void run()

{

while(flag)

{

String msg=receive();

System.out.println(msg);

}

}

private void release()

{

this.flag=false;

utils.close(dis,client);

}

}

在线聊天室

服务器:

public class Chat {

private static CopyOnWriteArrayList list=new CopyOnWriteArrayList<>();//使用并发容器,适合多线程

public static void main(String[]args) throws IOException

{

System.out.println("服务器启动中...");

ServerSocket server=new ServerSocket(9999);

while(true)

{

Socket client =server.accept();

System.out.println("一个客户端建立了连接");

channel c=new channel(client);

list.add(c); //容器管理所有成员

new Thread(c).start();

}

}

static class channel implements Runnable{

private DataInputStream dis;

private DataOutputStream dos;

private BufferedReader br;

private Socket client;

private boolean flag;

private String name;

public channel(Socket client)

{

this.client=client;

try {

dis=new DataInputStream(client.getInputStream());

dos=new DataOutputStream(client.getOutputStream());

flag=true;

//获取名称

this.name=receive();

//欢迎到来

this.send("欢迎来到聊天室");

this.sendothers(this.name+"来到了聊天室",true);

} catch (IOException e) {

release(); }

}

//接收消息

private String receive()

{

try {

String msg=dis.readUTF();

return msg;

} catch (IOException e) {

release();

}

return null;

}

//发送给消息

private void send(String msg)

{

try {

dos.writeUTF(msg);

dos.flush();

} catch (IOException e) {

release();

}

}

//群聊:获取自己的消息,发给其他人和私聊功能

private void sendothers(String msg,boolean issys)

{

boolean issecrete =msg.startsWith("@");

if(issecrete)

{

int index=msg.indexOf(":");

String target=msg.substring(1,index);

msg=msg.substring(index+1);

for(channel it:list)

{

if(it.name.equals(target)) //查找目标

{

it.send(this.name+"悄悄地对你说:"+msg); //私聊消息

break;

}

}

}else

{

for(channel it:list)

{

if(it==this)

{

continue;

}

if(!issys)

{

it.send(this.name+":"+msg);

}else

{

it.send(msg);

}

}

}

}

private void release()

{

this.flag=false;

utils.close(dis,dos,client); //写一个工具类,使用Closeable...可变参数

//退出时,从容器里面移掉自身

list.remove(this);

sendothers("离开了聊天室",false);

}

public void run()

{

while(flag)

{

String msg=receive();

sendothers(msg,false);

}

release();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值