Socket 实现(一对多)聊天室(多线程)代码+注释

1.使用server.accept()实现链接,开线程处理socket实例处理信息交互。
2.控制输出同时使用线程接收服务端返回的信息,
ps:
Server服务端代码如下:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
/**
 * 服务端
 * 处理多个client连接任务
 * @author natcheng
 *
 */
public class Server {
	private ServerSocket server;
	//所有的客户端信息流
	private Collection allpw = new ArrayList(); 
	/**
	 * 构造:初始成员变量
	 */
	public Server() {
		try {
			System.out.println("Server is starting...");
			server = new ServerSocket(8088);
			System.out.println("Server is ready!");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 服务端启动连接客户端并处理信息交互
	 */
	public void start() {
		try {
			//accept()方法对接客户端形成socket实例
			System.out.println("Ready for client...");
			Socket socket = server.accept();
			System.out.println("Connection succeeded!");
			//开线程接client
			Runnable r1 = new ClientHandler(socket);
			Thread t1 = new Thread(r1);
			t1.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 内部类,实现开线程接待Client中的Socket实例信息交互
	 * @author soft01
	 *
	 */
	private class ClientHandler implements Runnable{
		private Socket socket;
		private String host;
		/**
		 * 内部类构造,接accept()返回的socket
		 * @param socket
		 */
		public ClientHandler(Socket socket) {
		this.socket = socket;	
		InetAddress it = socket.getInetAddress();
		this.host = it.getHostAddress();
		}
		/**
		 * 线程方法run
		 */
		PrintWriter pw;
		public void run() {
			Thread t = Thread.currentThread();
			try {
				BufferedReader br = new BufferedReader(
						new InputStreamReader(socket.getInputStream(),"UTF-8"));
				 pw = new PrintWriter(
						new BufferedWriter(
								new OutputStreamWriter(
										socket.getOutputStream(),"UTF-8")),true);
				synchronized(allpw) {
					allpw.add(pw);
					System.out.println("同时在线人数:"+allpw.size());
				}
				String clientMsg = null;
				
				while(t.isAlive()) {
					if((clientMsg=br.readLine())!= null) {
					System.out.println(clientMsg);
					}
					//同时返回给各个客户端这条信息:
					synchronized(allpw) {
						for(PrintWriter everyPw:allpw) {
							everyPw.println(host+"说:"+clientMsg);
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				//下线踢除pw
				if(t.isInterrupted()) {
					synchronized(allpw) {
						allpw.remove(pw);
					}
					System.out.println(host+",offline!");
					//socket关闭
					try {
						socket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void main(String[] args) {
		Server server = new Server();
		server.start();
	}
}

Client 客户端代码如下:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
 * 客户端
 * @author soft01
 *
 */
public class Client {
	private Socket socket;
	/**
	 * 构造:初始化socket,连接服务端
	 */
	public Client() {
		try {
			System.out.println("Client is starting...");
			this.socket=new Socket("localhost",8088);
			System.out.println("Client start successfully!");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 启动信息交互
	 */
	public void start() {
		//发送信息(开线程)
		Runnable r = new OutputMsg();
		Thread t = new Thread(r);
		t.start();
		//接收信息
		try {
			BufferedReader br = new BufferedReader(
					new InputStreamReader(socket.getInputStream(),"UTF-8"));
			String serverMsg = null;
			while((serverMsg=br.readLine())!= null) {
				System.out.println(serverMsg);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private class OutputMsg implements Runnable{
		public void run() {
			try {
				PrintWriter pw = new PrintWriter(
						new BufferedWriter (
								new OutputStreamWriter(socket.getOutputStream(),"UTF-8")),true);
				System.out.println("input msg:");
				Scanner scan = new Scanner(System.in);
				String inputMsg = scan.nextLine();
				pw.println(inputMsg);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 主方法
	 * @param args
	 */
	public static void main(String[] args) {
		Client client = new Client();
		client.start();
	}
}

你可能感兴趣的:(Socket 实现(一对多)聊天室(多线程)代码+注释)