Java 网络在线聊天室 socket 极简风格

Java 网络聊天室 socket 极简版
两大类实现
涉及基本要素:
1. 多线程
2. 网络编程
3. TCP协议
4. 容器

效果图
在这里插入图片描述
分为客户端和服务器端

客户端服务器端
发送类封装管道类封装
接收类封装资源释放类 封装
资源释放类封装

客户端

package tcp;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {
	
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		System.out.println("----MINI在线聊天室----");
		Scanner scanner= new Scanner(System.in);
		//BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
		System.out.println("请输入名字:");
		String uname=scanner.nextLine();
		
		//建立连接
		Socket client=new Socket("localhost",8888);
		new Thread(new ClientSend(client, uname)).start();
		new Thread(new ClientReceive(client)).start();
		
	}
	
	//发送类 客户端的发送
	 static class ClientSend implements Runnable{
		private BufferedReader cmd;
		private DataOutputStream dos;
		private Socket client;
		private String uname;
		private boolean go=false;
		public  ClientSend(Socket client,String uname) 
		{
			this.client=client;
			this.uname=uname;
			
			cmd=new BufferedReader(new InputStreamReader(System.in));
			this.go=true;
			try {
				dos=new DataOutputStream(client.getOutputStream());
				//发送名字
				send(uname);
			} catch (IOException e) {
				e.printStackTrace();
				this.release();
			}
		} //构造器end
		 
		 
		 @Override
		public void run() 
		 {
			while(go)
			{
				String msg;
				try {
					msg=cmd.readLine();//从控制台获取消息
					if(!msg.equals("")) 
					{
						send(msg);
					}
				} catch (IOException e) {
					
					e.printStackTrace();
				}
			}
			
		}
		 //发送消息
		 private void send(String msg) 
		 {
			 try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				e.printStackTrace();
				release();
			}
		 }
		 //释放资源
		 private void release()
		 {	
			 this.go=false;
			 Clean.close(dos,client);
		 }
		
	}// ClientSend 类end
	
	//接收类 客户端接收
	 static class ClientReceive implements Runnable{
		private DataInputStream dis;
		private Socket client;
		private boolean go=false;
		
		public  ClientReceive(Socket client) 
		{
			this.client=client;
			this.go=true;
			try {
				this.dis=new DataInputStream(client.getInputStream());
			} catch (IOException e) {
				
				e.printStackTrace();
				this.release();
			}
		}
		//接收消息
		 private String receive()
		 {
			 String msg="";
			 try {
				msg=dis.readUTF();
			} catch (IOException e) {
				
				e.printStackTrace();
				this.release();
			}
			 return msg;
		 }
		 @Override
		public void run() {
			while(go)
			{
				String msg=this.receive();
				if(!msg.equals(""))
				{
					System.out.println(msg);
				}
			}
			
		}
		//释放资源
		 private void release()
		 {	
			 this.go=false;
			 Clean.close(this.dis,this.client);
		 }
	}//ClientReceive 类end
	
	
	
	//释放资源类封装
	 static  class Clean {
		public static void close(Closeable... targets) {
			for(Closeable target:targets) {
				try {
					if(null!=target) {
						target.close();
					}
				}catch(Exception e) {
					e.printStackTrace();
				}
				
			}
			
		}
	}//clean类end
}

服务器端

package tcp;

import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;



public class ChatServer {
		private static CopyOnWriteArrayList<Channel>userArrayList=new CopyOnWriteArrayList<Channel>();
		public static void main(String[] args) throws IOException {
			ServerSocket server=new ServerSocket(8888);
			System.out.println("----server-----");
		
			while(true) {
				Socket client=server.accept();
				System.out.println("客户进行连接了");
				Channel user=new Channel(client);
				userArrayList.add(user);
				new Thread(user).start();
			}
			
		}
		static class Channel implements Runnable{
			private DataInputStream dis;
			private DataOutputStream dos;
			private Socket client;
			private boolean go;
			private String uname;
			public Channel(Socket client) {
				this.client=client;
				
				try {
					dis=new DataInputStream(client.getInputStream());
					dos=new DataOutputStream(client.getOutputStream());
					this.go=true;
					this.uname=receive();
					
					this.send("欢迎加入");
					this.sendOthers(uname+"加入聊天室",true);
				} catch (IOException e) {
					e.printStackTrace();
					this.release();
				}
			}
			
			
			//接受消息
			private String receive() {
				String msg="";
				try {
					msg=dis.readUTF();
				} catch (IOException e) {
					e.printStackTrace();
					this.release();
				}
				return msg;
			}
			//发送消息
			private void send(String msg) {
				try {
					dos.writeUTF(msg);
					dos.flush();
				} catch (IOException e) {
					
					e.printStackTrace();
					this.release();
				}
			}
			private void sendOthers(String msg,boolean System) {
				boolean isPrivate=msg.startsWith("@");
				if(isPrivate)
				{
					//私聊
					//私聊格式@name:
					int index=msg.indexOf(":");
					String targetname=msg.substring(1,index);
					msg=msg.substring(index+1);
					for(Channel other:userArrayList)
					{
						if(other.uname.equals(targetname))
						{
							other.send(this.uname +"悄悄地对您说:"+msg);
							break;
						}
					}
				}else {				
						for(Channel other: userArrayList) {
							if(other==this) { //自己
								continue;
							}
							if(!System) {
								other.send(this.uname +"对所有人说:"+msg);//群聊消息
							}else {
								other.send(msg); //系统消息
							}
				}
				
				}
			}
			//释放资源
			private void release() {
				this.go=false;
				Clean.close(dis,dos,client);
				//删掉离开的人员
				userArrayList.remove(this);
				sendOthers(this.uname+"离开已离开聊天室...",true);
			}
			@Override
			public void run() {
				while (go) {
					String msg=this.receive();
					if(!msg.equals("")) {
						sendOthers(msg, false);
					}
				}
				
			}
			
		}//Channel类 end
		
		//释放资源类封装
		 static  class Clean {
			public static void close(Closeable... targets) {
				for(Closeable target:targets) {
					try {
						if(null!=target) {
							target.close();
						}
					}catch(Exception e) {
						e.printStackTrace();
						System.out.println("---clean------");
					}
					
				}
				
			}
		}//clean类end
}

客户端接收和发送类继承Runnable接口重写run()方法实现接收发送同时进行不阻塞。
服务端管道类类继承Runnable接口重写run()方法,每当有一个用户登录就产生一个连接管道并加入容器,实现并发交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值