基於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) {
			}
		}
	}
}


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