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

来源:互联网 发布:陌生人语音聊天软件 编辑:程序博客网 时间:2024/05/21 09:19
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+"进入聊天室");}}@Overridepublic 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);}}@Overridepublic 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;}}@Overridepublic 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) {}}}}