⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatserver_mashibing.java

📁 Socket聊天室服务器端的源代码
💻 JAVA
字号:
package local;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import sun.misc.Cleaner;

public class ChatServer_mashibing {

	boolean started = false; // started变量用于判断服务器端是否已启动

	ServerSocket server = null;

	List<Client> list = new ArrayList<Client>();// 声明一个集合,用于存放处理接受客户端数据的Client类对象,因为在Client类里声明了socket和bufferedReader,所以存放Client类对象最合适,因为不用再定义相关流

	public void init() {
		try {
			server = new ServerSocket(6214);
			started = true;
		} catch (BindException e) {
			System.out.println("端口使用中!!!");
			System.out.println("请先关掉端口!!");
			System.exit(0);
			e.printStackTrace();
		} catch (IOException e1) {
			System.out.println("不能提供端口!!!");
		}
		try {
			while (true) {
				Socket soc = server.accept();
				Client c = new Client(soc,list);
				list.add(c); // 把处理客户端数据的每一个Client对象存到集合clients里面
				System.out.println("A client connected");// 用于调试客户端是否已连上!!
				new Client(soc,list).start();
				
			}
		} catch (IOException e) {
			// e.printStackTrace(); 该句不用打印,不然在控制台会报错
			System.out.println("Client closed!!"); // 当客户端断开时,即IOException,需要打印该句!
			return;
		} finally {
			try {
				server.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		new ChatServer_mashibing().init();
	}
}

/**
 * 建立一个内部类专门处理来自各个客户端的数据信息,所以起名Client,与客户端对应起来!!!
 */
class Client extends Thread {

	private Socket soc = null;

	private BufferedReader dis = null;

	private PrintStream ps = null;

	String str = null; // Str用于读取客户端的信息

	List<Client> clients = new ArrayList<Client>();

	public Client(Socket soc,List<Client> clients) {
		this.soc = soc;
		this.clients = clients;
		try {
			dis = new BufferedReader(
					new InputStreamReader(soc.getInputStream()));
			ps = new PrintStream(soc.getOutputStream());
		} catch (IOException e) {
			System.out.println();
			e.printStackTrace();
		}
	}

	/**
	 * 定义一个方法用于将信息群发给客户端
	 */
	public void send(String str) {
		ps.println(str);
	}

	public void run() {
		synchronized (this) {
			System.out.println(this);
			try {
				// 如果客户端不关闭且信息不为null,则把它打印出来!!
				while ((str = dis.readLine()) != null) {
					System.out.println(str); // 将客户端的信息打印到服务端的控制台上
					System.out.println("The size: " +clients.size());
					for (int i = 0; i < clients.size(); i++) {
						Client c = clients.get(i);
						c.send(str);
						System.out.println("群发成功!!!");
					}

					// Iterator<Client> iter = clients.iterator();
					// while (iter.hasNext()) {
					// Client c = (Client) iter.next();
					// c.send(str);
					// System.out.println("群发OK");
					// }

				}
				System.out.println("Client closed!!"); // 当客户端关闭时,打印该语句!!
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				// 当客户端close时,应当作IOException,需要以下处理
				try {
					if (dis != null)
						dis.close(); // 当客户端关闭时,作为对应,需要把输入流关闭。
					if (ps != null)
						ps.close(); // 当客户端关闭时,作为对应,需要把输出流关闭。
					if (soc != null) {
						soc.close(); // 当客户端关闭时,作为对应,服务端这边的socket也需关掉。
						soc = null;
					}

				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					System.out.println("Client closed!!"); // 当客户端断开时,即IOException,需要打印该句!
					return;
				}
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -