用JAVA实现一个聊天室(四)

是一篇博客中,我们对客户端进行了改造。客户端可以实现多线程,那么服务器端也应该进行改造。服务器端应该分别多个客户端,然后分别进行发送信息,比如,群聊或者是私聊。可以利用之前的容器,建立一个容器进行储存。

并且,我们写一个内部类,方便对服务器端的资源进行访问。

可以看看具体代码

//服务器端代码
package Test02;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;


public class Server {
	private List<Mychannel> all=new ArrayList<Mychannel>();
	public static void main(String[] args) {
		new Server().start();
	}
	public void start() {
		try {
			ServerSocket serverSocket = new ServerSocket(7777);
			while(true) {
				Socket client=serverSocket.accept();
				Mychannel mychannel=new Mychannel(client);
				all.add(mychannel);
				new Thread(mychannel).start();
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	//private List<Mychannel> all=new ArrayList<Mychannel>();
	public class Mychannel implements Runnable{

		@Override
		public void run() {
			while(isrunning) {
				sendOther(MyReceive());
			}
			
		}
		private boolean isrunning=true;
		private DataInputStream dis;
		private DataOutputStream dos;
		private String name;
		public String MyReceive() {
			String string="";
			try {
				string=dis.readUTF();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				isrunning=false;
				CloseUtil.Closeall(dis);
			}
			return string;
			
		}
		public void Mysend(String meg) {
			try {
				dos.writeUTF(meg);
				dos.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				isrunning=false;
				CloseUtil.Closeall(dos);
				
			}
		}
		public void sendOther(String meg) {
			if(meg.startsWith("@")) {
				String name;
				String text;
				name= meg.substring(0,meg.indexOf(":"));
				text=meg.substring(meg.indexOf(":")+1,meg.length());
				for(Mychannel temp:all) {
					if(temp.name.equals(name)) {
						temp.Mysend(this.name+"悄悄对你说"+text);
					}
				}
			}else {
				for(Mychannel temp:all) {
					if(temp==this) {
						continue;
					}else {
						temp.Mysend(this.name+"对所有人说:"+meg);
					}
				}
			}
			/*for(Mychannel temp:all) {
				temp.Mysend(meg);
			}*/
		}
		public Mychannel(Socket client) {
			super();
			try {
				dis=new DataInputStream(client.getInputStream());
				dos=new DataOutputStream(client.getOutputStream());
				name=dis.readUTF();
				Mysend("欢迎您进入聊天室");
				sendOther(this.name+"进入聊天室");
				
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				isrunning=false;
				CloseUtil.Closeall(dis,dos);
				all.remove(this);
			}
			
			
		}
		public Mychannel() {
			super();
		}
		
	}
}
客户端代码
package Test02;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
	public static void main(String[] args) {
		try {
			Socket client=new Socket(InetAddress.getLocalHost(),7777);
			System.out.println("请输入姓名:");
			BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			String name=br.readLine();
			if (name.equals("")) {
				return ;
			}
			new Thread(new Send(client, name)).start();
			new Thread(new Receive(client)).start();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
}
//客户端的多线程
package Test02;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Send implements Runnable{
	private DataOutputStream dos;
	private boolean isrunning=true;
	private BufferedReader console;
	private String name;
	
	
	public Send(Socket client,String name) {
		this();//一定要调用this,否则会报空指针异常,这是因为没有调用this构造出consle类
		try {
			dos=new DataOutputStream(client.getOutputStream());
			this.name=name;
			send(this.name);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			isrunning=false;
			CloseUtil.Closeall(dos);
		}
		
	}
	public Send() {
		super();
		 console=new BufferedReader(new InputStreamReader(System.in));
	}
	public void send(String string) {
		if(null!=string&&!string.equals("")) {
			try {
				dos.writeUTF(string);
				dos.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				CloseUtil.Closeall(dos);
				isrunning=false;
			}
		}
	}
	public String getInfo() {
		try {
			return console.readLine();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	@Override
	public void run() {
		while(isrunning) {//一定是while,麻痹上头写成if了,上头了
			send(getInfo());
		}
	}
}
//客户端的多线程
package Test02;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

public class Receive implements Runnable{
	private DataInputStream dis;
	private boolean isrunning=true;
	

	public Receive(Socket client) {
		super();
		try {
			dis=new DataInputStream(client.getInputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			isrunning=false;
			CloseUtil.Closeall(dis);
		}
		
	}
	public Receive() {
		super();
	}
	public String receive() {
		String string="";
		try {
			string=dis.readUTF();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			isrunning=false;
			CloseUtil.Closeall(dis);
		}
		return string;
		
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(isrunning) {
			System.out.println(receive());
		}
	}

}

测试

从测试结果,看到,还有一些小的BUG,明天我们将进行修改,完善。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值