Java_193_网络编程_手写聊天室终极版_私聊_startsWith_indexOf_substring

Server[修改sends()方法实现]

package TalkTCPSocket;

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

/**
 * 在线聊天室:客户端 
 * 目标:使用多线程实现多个客户可以正常收发多条消息
 * 问题:其他客户必须等待之前的客户退出,才能继续排队
 * 
 * @author pmc
 *
 */
public class TChatServer5 {
	private static CopyOnWriteArrayList all=new CopyOnWriteArrayList();
	public static void main(String[] args) throws IOException {
		System.out.println("-----Server-----");
		// 指定端口使用ServerSocket
		ServerSocket server = new ServerSocket(8885);
		// 阻塞式等待连接accept
		while (true) {
			Socket client = server.accept();
			System.out.println("已建立连接");
			// 服务端接收数据
			// 读取客户端信息
			Chat c=new Chat(client);
			all.add(c);//管理所有成员
			new Thread(c).start();
		}
		// server.close();
	}

	static class Chat implements Runnable{
		private DataInputStream re;
		private DataOutputStream out;
		private Socket client;
		private boolean isRunning;
		private String name;
		public Chat(Socket client){
			this.client=client;
			try {
				re=new DataInputStream(client.getInputStream());
				out=new DataOutputStream(client.getOutputStream());
				isRunning=true;
				//接收名称
				this.name=receive();
				this.send(this.name+",欢迎回来");
				this.sends("欢迎"+this.name+"加入群聊",true);//是系统消息
			} catch (IOException e) {
				close();
			}
		}
		// 接收消息
		private String receive() {
			String msg = "";
			try {
				msg = re.readUTF();
				return msg;
			} catch (IOException e) {
				System.out.println("---接收---");
				close();
			}
			return "";
		}

		// 发送给自己消息
		private void send(String msg) {
			try {
				out.writeUTF(msg);
				out.flush();
			} catch (IOException e) {
				System.out.println("---发送---");
				close();
			}
		}
		/**
		 * 群聊:获取自己的消息,发给其他人
		 * @param msg
		 * @param flag
		 */
		// 群发消息
		private void sends(String msg,boolean flag) {//flag是否系统消息
			boolean isPrivate=msg.startsWith("@");//检测字符串是否以指定的前缀开始
			if(isPrivate){
				int idx=msg.indexOf(":");//返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
				String targetName=msg.substring(1,idx);//取出@后面的name
				msg=msg.substring(idx+1);//取出“:”后面的消息
				for (Chat temp : all) {
					if(temp.name.equals(targetName)){
						temp.send("《"+this.name+"》对你说:"+msg);
					}
				}
			}else{
				for (Chat temp : all) {
					if(temp==this){
						continue;
					}
					if(!flag){
						temp.send("《"+name+"》对所有人说:"+msg);
					}else{
						temp.send(msg);//系统消息
					}
				}
			}
		}
		// 释放资源
		private void close() {
			this.isRunning=false;
			Utils.close(re,out,client);
			this.sends(this.name+",退出了群聊", true);
			all.remove(this);//去除自己
		}
		@Override
		public void run() {
			while(isRunning){
				String msg=receive();
//				System.out.println(msg);
				if(!msg.equals("")){
//					send(msg);
					sends(msg,false);//不是系统消息
				}
			}
		}
	}
}

Client

package TalkTCPSocket;

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

/**
 * 在线聊天室:客户端
 * 目标:使用多线程实现多个客户可以正常收发多条消息
 * 问题:其他客户必须等待之前的客户退出,才能继续排队
 * @author pmc
 *
 */
public class TChatClient5 {
	public static void main(String[] args) throws IOException {
		System.out.println("-----Client-----");
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		System.out.println("请输入用户名:");
		String name=br.readLine();
		// 建立连接,使用Socket创建客户端+服务的地址和端口
		Socket client = new Socket("192.168.10.100", 8885);
		// 客户端发送消息
		// 读取键盘信息
		 new Thread(new TChatClient4Send(client,name)).start();
		 new Thread(new TChatClient4Receive(client)).start();
		 
	}
}

Clientsend

package TalkTCPSocket;

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

/**
 * 发送端
 * @author pmc
 *
 */
public class TChatClient4Send implements Runnable{
	private BufferedReader re;
	private DataOutputStream out;
	private Socket client;
	private boolean isRunning;
	private String name;
	public TChatClient4Send(Socket client,String name){
		this.name=name;
		this.client=client;
		this.isRunning=true;
		System.out.println("Send:"+isRunning);
		re=new BufferedReader(new InputStreamReader(System.in));
		try {
			out=new DataOutputStream(client.getOutputStream());
			msgs(name);
		} catch (IOException e) {
			System.out.println("C_1");
			cls();
		}
	}
	//发送消息
	public void msgs(String msg){
		try {
			out.writeUTF(msg);
			out.flush();
		} catch (IOException e) {
			System.out.println("C_2");
			cls();
		}
	}
	//获取控制台输入
	public String str(){
		String msg="";
		try {
			msg=re.readLine();
			return msg;
		} catch (IOException e) {
			System.out.println("C_3");
			cls();
		}
		return msg;
	}
	public void cls(){
		this.isRunning=false;
		Utils.close(re,out,client);
	}
	@Override
	public void run() {
		while(isRunning){
			String msg=str();
			if(!msg.equals("")){
				msgs(msg);	
			}
		}
	}
}

Clientreceive

package TalkTCPSocket;

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

/**
 * 接收端
 * @author pmc
 *
 */
public class TChatClient4Receive implements Runnable{
	private DataInputStream in;
	private Socket client;
	private boolean isRunning;
	public TChatClient4Receive(Socket client){
		this.client=client;
		this.isRunning=true;
		System.out.println("Receive:"+isRunning);
		try {
			in=new DataInputStream(client.getInputStream());
			
		} catch (IOException e) {
			System.out.println("R_1");
			cls();
		}	
	}
	
	public String receive(){
		String str = "";
		try {
			str = in.readUTF();
//			System.out.println("服务器返回信息:"+str);
		} catch (IOException e) {
			System.out.println("R_2");
			cls();
		}
		return str;
	}
	public void cls(){
		this.isRunning=false;
		Utils.close(in,client);
	}
	@Override
	public void run() {
		while(isRunning){
			String msg=receive();
			if(!msg.equals("")){
				System.out.println(msg);
			}
		}
	}
}

 

你可能感兴趣的:(Java_笔记)