基于ServerSocket的多人聊天室模拟实现

package chatroom;

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;
/**
 * 利用ServerSocket实现的多人聊天
 * @author 风潇潇
 *
 */
public class Server {
	//所有封装后的客户端通道的集合
	List<MyTunnel> chatRoom = new ArrayList<MyTunnel>();
	public static void main(String[] args) throws IOException {
		new Server().start();
	}
	public void start() throws IOException{
		//以8888端口创建服务端
		ServerSocket sever = new ServerSocket(8888);
		//依据接收到的请求,为每个client创建通道并开启单独县城
		while(true){
			Socket client = sever.accept();
			MyTunnel mt = new MyTunnel(client);
			chatRoom.add(mt);
			new Thread(mt).start();
			
		}
	}
	/**
	 * 将客户端收发信息封装为内部类,便于使用
	 * @author 风潇潇
	 *
	 */
	private class MyTunnel implements Runnable{
		private DataOutputStream dos;
		private DataInputStream dis;
		boolean isRunning=true;
		private String name ;
		//初始化,创建输入流输出流同client建立联系
		public MyTunnel(Socket client) {
			try {
				dos = new DataOutputStream(client.getOutputStream());
				dis = new DataInputStream(client.getInputStream());
			} catch (IOException e) {
				isRunning=false;
				CloseUtil.Close.closeAll(dos,dis);
			}
		}
		//用户名设置
		public void setName(String name){
			this.name=name;
		}
		//从用户处收取消息
		private String getMsg(){
			String msg =null;
			try {
				msg=dis.readUTF();
			} catch (IOException e) {
				isRunning=false;
				CloseUtil.Close.closeAll(dos,dis);
				chatRoom.remove(this);
			}
			return msg;
		}
		//向用户发送消息
		public void send(String msg){
			if(msg==null){
				return;
			}
			try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				isRunning=false;
				CloseUtil.Close.closeAll(dos,dis);
				chatRoom.remove(this);
			}
		}
		//聊天室和私聊
		public void sendAll(){
			String msg = this.getMsg();
			if(msg!=null&&msg.startsWith("@")&&msg.contains(":")){
				String name = msg.substring(1, msg.indexOf(':'));
				String content = msg.substring(msg.indexOf(':')+1);
				for(MyTunnel mt:chatRoom){
					if(mt.name.equals(name)){
						mt.send(this.name+"的悄悄话:"+content);
					}
					else{
						this.send(name+"用户不存在");
					}
				}
			}else{
				for(MyTunnel mt:chatRoom){
					if(mt==this){
						continue;
					}
					mt.send(this.name+":"+msg);
				}
			}
		}
		//初始化用户,接受用户端用户名,并发送欢迎消息
		public void iniClient(){
			String name = this.getMsg();
			this.setName(name);
			for(MyTunnel mt:chatRoom){
				if(mt==this){
					continue;
				}
				mt.send("欢迎"+name+"进入聊天室");
			}
		}
		@Override
		public void run() {
			iniClient();
			while(isRunning){
				sendAll();
			}
		}
		
	}

}


package chatroom;

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

public class Client {
//用户名设置与线程启动
	public static void main(String[] args) throws UnknownHostException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String name=null;
		do{
			System.out.println("欢迎使用请输入你的用户名:");
			name = br.readLine();
		}while(null==name||name.equals(""));
		br.close();
		Socket client = new Socket("localhost",8888);
		new Thread(new Input(client)).start();;
		new Thread(new Output(client,name)).start();;
	}
}
//接受消息
class Input implements Runnable{
	private DataInputStream dis;
	private boolean isRunning = true;
	public Input(Socket client) {
		try {
			dis=new DataInputStream(client.getInputStream());
		} catch (IOException e) {
				CloseUtil.Close.closeAll(dis);
				isRunning=false;
		}
	}
	//从服务器接收消息
	private String getMsg(){
		String msg=null;
		try {
			msg=dis.readUTF();
		} catch (IOException e) {
			CloseUtil.Close.closeAll(dis);
			isRunning=false;
		}
		return msg;
	}
	//将消息打印至控制台
	public void print(){
		String msg = this.getMsg();
		if(msg!=null){
			System.out.println(msg);
		}
		
	}
	@Override
	public void run() {
		while(isRunning){
			print();
		}
	}
	
}

//发送消息
class Output implements Runnable{
	private DataOutputStream dos;
	private BufferedReader br;
	private boolean isRunning = true;
	public Output(Socket client,String name) {
		try {
			this.dos = new DataOutputStream(client.getOutputStream());
			this.br = new BufferedReader(new InputStreamReader(System.in));
			this.dos.writeUTF(name);
		} catch (IOException e) {
			CloseUtil.Close.closeAll(dos,br);
			isRunning=false;
		}
		
	}
	//从控制台读入消息
	private String getMsg(){
		String msg = null;
		try {
			msg = br.readLine();
		} catch (IOException e) {
			CloseUtil.Close.closeAll(dos,br);
			isRunning=false;
		}
		return msg;
	}
	//将消息发送至服务器
	public void send(){
		String msg = getMsg();
		try {
			if(msg!=null){
				dos.writeUTF(msg);
				dos.flush();
			}
		} catch (IOException e) {
			CloseUtil.Close.closeAll(dos,br);
			isRunning=false;
		}
	}
	
	@Override
	public void run() {
		while(isRunning){	
			send();
		}
		
	}
	
}

package CloseUtil;

import java.io.Closeable;
import java.io.IOException;

public class Close {
	public static void closeAll(Closeable... io) {
		for(Closeable c:io){
			try {
				if(c!=null){
					c.close();
				}
			} catch (IOException e) {
			}
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章