惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
P
Proofpoint News Feed
The Last Watchdog
The Last Watchdog
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News | PayPal Newsroom
Application and Cybersecurity Blog
Application and Cybersecurity Blog
O
OpenAI News
S
Security @ Cisco Blogs
宝玉的分享
宝玉的分享
Hacker News: Ask HN
Hacker News: Ask HN
T
Troy Hunt's Blog
Google Online Security Blog
Google Online Security Blog
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
TaoSecurity Blog
TaoSecurity Blog
Help Net Security
Help Net Security
Latest news
Latest news
NISL@THU
NISL@THU
S
Security Affairs
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
AI
AI
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Announcements
Recent Announcements
P
Privacy & Cybersecurity Law Blog
小众软件
小众软件
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美
AWS News Blog
AWS News Blog
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
I
InfoQ
Schneier on Security
Schneier on Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Exploit Database - CXSecurity.com
IT之家
IT之家
T
Threatpost
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
腾讯CDC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
News and Events Feed by Topic
L
LINUX DO - 最新话题
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
H
Heimdal Security Blog
S
SegmentFault 最新的问题

Y先生的火箭屋

Java常用代码工具类 - Y先生的火箭屋 软件的七大设计原则 - Y先生的火箭屋 天天基金中持仓收益率和持有收益率的区别 - Y先生的火箭屋 在N个球中用天平称最少次数找出坏球 - Y先生的火箭屋 MySQL新增排名字段 - Y先生的火箭屋 Java中23种设计模式 - Y先生的火箭屋 金融上的做多做空和杠杆 - Y先生的火箭屋 JVM调优常用的调优参数 - Y先生的火箭屋 基于EasyExcel的配置型导入导出V1.0 - Y先生的火箭屋
JavaSE使用socket与线程实现控制台版的聊天室功能 - Y先生的火箭屋
Y先生 · 2022-07-22 · via Y先生的火箭屋

服务器server端

	private ServerSocket server;// 创建了ServerSocket对象
	// 存放所有客户端输出流的集合,并初始化
	private List<PrintWriter> allOut = new ArrayList<PrintWriter>();
 
	// 向集合中添加元素
	private synchronized void addOut(PrintWriter out) {
		allOut.add(out);
	}
 
	// 从集合中删除元素
	private synchronized void removeOut(PrintWriter out) {
		allOut.remove(out);
	}
 
	// 遍历集合向所有的客户端发送信息
	private synchronized void sendMessage(String msg) {
		for (PrintWriter out : allOut) {
			out.println(msg);
		}
 
	}
 
	/**
	 * 构造方法,用来初始化ServerSocket
	 * 
	 * @throws IOException
	 */
	public Server() throws IOException {
		try {
			server = new ServerSocket(8088);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
	}
 
	public void start() throws IOException {
		while (true) {
			try {
				Socket socket = server.accept();
				/**
				 * 当一个客户端连接后,应该启动一个线程,来负责与客户端的交互 这样才能循环接待不同的客户端
				 */
				ClientHandler hander = new ClientHandler(socket);
				Thread thread = new Thread(hander);
				// 启动线程
				thread.start();
			} catch (IOException e) {
				e.printStackTrace();
				throw e;
			}
		}
	}
 
	public static void main(String[] args) {
		Server server = null;
		try {
			server = new Server();
			server.start();
		} catch (IOException e) {
			System.out.println("服务器启动失败");
		}
	}
 
	/**
	 * 启动线程的成员内部类
	 * 
	 * @author Admin
	 * 
	 */
 
	class ClientHandler implements Runnable {
		private Socket socket;
 
		public ClientHandler(Socket socket) {
			this.socket = socket;
		}
 
		@Override
		public void run() {
			PrintWriter writer = null;
			try {
				// 向客户端发送信息
				writer = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream(), "utf-8"), true);
				addOut(writer);
				// 读取客户端的信息
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(socket.getInputStream(), "utf-8"));
				String msg = null;
 
				while ((msg = reader.readLine()) != null) {
					// 将客户端发送过来的信息转发给客户端
					sendMessage(msg);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				// 处理客户端断开连接后的工作
				// 将客户端的输出流从集合中移除
				removeOut(writer);
			}
		}
	}

客户端client端

	// 创建与服务端通讯的Socket
	private Socket socket;
 
	public Client() throws IOException {
		try {
			socket = new Socket("localhost", 8088);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
	}
 
	// 客户端开始工作的方法
	public void start() {
		// 启动线程,用于读取服务端发送过来的信息
		ServerHandler handler = new ServerHandler();
		Thread thread = new Thread(handler);
		// 启动线程
		thread.start();
		/**
		 * 循环从控制台输入信息发送至服务端
		 */
		Scanner sca = new Scanner(System.in);
		try {
			PrintWriter writer = new PrintWriter(new OutputStreamWriter(
					socket.getOutputStream(), "utf-8"), true);
			String msg = null;
			while (true) {
				msg = sca.nextLine();
				writer.println(msg);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
 
	public static void main(String[] args) {
		Client c = null;
		try {
			c = new Client();
			c.start();
		} catch (IOException e) {
			System.out.println("连接失败");
		}
	}
 
	// 读取服务端发送过来的信息的线程
	class ServerHandler implements Runnable {
 
		@Override
		public void run() {
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(socket.getInputStream(), "utf-8"));
				String msg = null;
				while ((msg = reader.readLine()) != null) {
					System.out.println(msg);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

|´・ω・)ノ

ヾ(≧∇≦*)ゝ

(☆ω☆)

(╯‵□′)╯︵┴─┴

 ̄﹃ ̄

(/ω\)

∠( ᐛ 」∠)_

(๑•̀ㅁ•́ฅ)

→_→

୧(๑•̀⌄•́๑)૭

٩(ˊᗜˋ*)و

(ノ°ο°)ノ

(´இ皿இ`)

⌇●﹏●⌇

(ฅ´ω`ฅ)

(╯°A°)╯︵○○○

φ( ̄∇ ̄o)

ヾ(´・ ・`。)ノ"

( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃

(ó﹏ò。)

Σ(っ °Д °;)っ

( ,,´・ω・)ノ"(´っω・`。)

╮(╯▽╰)╭

o(*////▽////*)q

>﹏<

( ๑´•ω•) "(ㆆᴗㆆ)

😂

😀

😅

😊

🙂

🙃

😌

😍

😘

😜

😝

😏

😒

🙄

😳

😡

😔

😫

😱

😭

💩

👻

🙌

🖕

👍

👫

👬

👭

🌚

🌝

🙈

💊

😶

🙏

🍦

🍉

😣

Source: github.com/k4yt3x/flowerhd