Java NIO实现简单聊天室(GUI版)

基于Python guI的多人聊天室的设计与实现 现在,即时聊天系统已成为 Internet 上的主要交流工具,并且涌现出大量的AP和平台。这些AP和平台都拥有更加完善的交换机制,使得人们可以更加便捷地进行沟通和交换信息。广域网的聊天系统多重多样,知名的软件主要有 Facebook、腾讯 QQ 等。局域网聊天通信软件也有很多,最著名的应该是飞秋。为了学习和应用 Windows 网络通信编程,我们学习了相关知识,为了应用实践,使用网络通信中的 TCP 和 UDP 编程,实现了多人在线聊天系统。 阅读详情

Java NIO实现简单聊天室(GUI版)

登录界面:

package com.chatroom;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

import com.chat.client.ChatFrame;
import com.chat.client.ClientService;


/*
 * 登录聊天室
 */
public class LoginFrame extends JFrame{
	static final long serialVersionUID = 1L;
	static JTextField txtName;
	static JButton btnOK;
	static JLabel label;
	
	public LoginFrame() {
		this.setLayout(null);
		Toolkit kit = Toolkit.getDefaultToolkit();
		int w = kit.getScreenSize().width;
		int h = kit.getScreenSize().height;
		this.setBounds(w / 2 - 230 / 2, h / 2 - 200 / 2, 230, 200);
		this.setTitle("设置名称");
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setResizable(false);
		txtName = new JTextField(4);
		this.add(txtName);
		txtName.setBounds(10, 10, 100, 25);
		btnOK = new JButton("OK");
		this.add(btnOK);
		btnOK.setBounds(120, 10, 80, 25);
		label = new JLabel("[w:" + w + ",h:" + h + "]");
		this.add(label);
		label.setBounds(10, 40, 200, 100);
		label.setText("<html>在上面的文本框中输入名字<br/>显示器宽度:" + w + "<br/>显示器高度:" + h
				+ "</html>");
		
		
		btnOK.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String uname = txtName.getText();
				ClientService service = ClientService.getInstance();
				ChatFrame chatFrame = new ChatFrame(service, uname);
				chatFrame.show();
				setVisible(false);
			}
		});
		
	}
	
	public static void main(String[] args) {
			LoginFrame loginFrame = new LoginFrame();
			loginFrame.setVisible(true);
	}

}

服务端:

package com.chatroom;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;



public class ChatServer implements Runnable{
		Selector selector;
		SelectionKey  selectionKey;
		boolean isRunning;
		Vector<String> usernames;//用来存放用户的名字
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		public ChatServer(int port) throws IOException {
				isRunning = true;
				usernames = new Vector<>();
				init(port);
		}
		private void printInfo(String str) {
			System.out.println("[" + sdf.format(new Date()) + "] -> " + str);
		}
		
		
		/*
		 * 初始化,启动服务器
		 */
		public void init(int port) throws IOException {
				selector=Selector.open();
				ServerSocketChannel server = ServerSocketChannel.open();
				server.socket().bind(new InetSocketAddress(port));
				server.configureBlocking(false);
				selectionKey = server.register(selector, SelectionKey.OP_ACCEPT);
				printInfo("启动服务器");
		}
		@Override
		public void run() {
			
			try {
					while (isRunning) {
						int n=selector.select();
						if (n>0) {
							Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
							while (iterator.hasNext()) {
								SelectionKey key = iterator.next();
								/*
								 * 如有客户端进来则进行连接
								 */
								if (key.isAcceptable()) {
									ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
									SocketChannel socketChannel = serverSocketChannel.accept();
									if (socketChannel==null) {
										continue;
									}
									socketChannel.configureBlocking(false);
									socketChannel.register(selector, SelectionKey.OP_READ);
								}
								if (key.isReadable()) {
									readMsg(key);
								}
								
								if (key.isWritable()) {
									writeMsg(key);
								}
								
								
							}
						}
						
					}
			} catch (Exception e) {
				// TODO: handle exception
			}
			
		}
		
		/*
		 * 读取信息
		 */
		public void readMsg(SelectionKey key) throws IOException {
				SocketChannel socketChannel = (SocketChannel) key.channel();
				ByteBuffer buffer = ByteBuffer.allocate(1024);
				StringBuffer sBuffer = new StringBuffer();
				int count = socketChannel.read(buffer);//读取从客户端传过来的信息大小
				
				/*
				 * 如果有信息则加到StringBuffer中
				 */
				if (count>0) {
					buffer.flip();
					sBuffer.append(new String(buffer.array(), 0, count));
				}
				/*将信息转换成字符串*/
				String string = sBuffer.toString();
				
				/*
				 * 处理用户上线的情况
				 */
				if (string.indexOf("open_") != -1) {
					String name = string.substring(5);
					printInfo(name+"上线");
					usernames.add(name);
					Iterator<SelectionKey> sIterator = selector.selectedKeys().iterator();
					while (sIterator.hasNext()) {
						SelectionKey keyss = sIterator.next();
						if (keyss!=selectionKey) {
							keyss.attach(usernames);
							keyss.interestOps(keyss.interestOps() | SelectionKey.OP_WRITE);
							
						}
					}
					/*
					 * 处理用户下线的情况
					 */
				} else if (string.indexOf("exit_") != -1) {
					String username = string.substring(5);
					usernames.remove(username);
					key.attach("close");
					key.interestOps(SelectionKey.OP_WRITE);
					Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
					while (iterator.hasNext()) {
						SelectionKey sKey = iterator.next();
						
Java实现的多线程聊天室简易教程 本文还有配套的精品资源,点击获取 简介:本项目通过Java编程语言实现了一个简易的多线程聊天室,涉及到网络编程、并发处理和用户交互等核心领域。项目重点在于Java Socket编程、多线程处理和聊天室的基本功能实现,包括用户登录、消息发送/接收和退出聊天室。通过源代码分析,学习者可以掌握如何创建和管理线程、网络通信以及聊天室消息传递机制。 1. Java Sock... 阅读详情

相关推荐

一文读懂无人机AI识别算法,原理、技术、应用

本文详细介绍了无人机识别算法的工作原理、技术优势以及在多个行业的应用前景,展现了其在提升安全监控、资源管理和应急响应中的关键作用。尽管无人机识别算法在多个领域展现出巨大潜力,但仍面临技术挑战,如算法的准确性、数据的实时处理能力以及对复杂环境的适应性。4. 消防与城市管理: 无人机识别算法在消防和城市管理中的应用,为相关部门提供了及时的信息支持,提升了应急处置能力和城市管理水平。1. 公安监控: 无人机识别算法在公安领域的应用,可以实时识别犯罪嫌疑人和违法行为,有效提升城市治安管理的智能化水平。

foiadrone的博客 1849

从“跳变”到“连续”:深入理解霍尔传感器插值与PLL角度估算的优劣与选择

本文深入解析霍尔传感器角度估算技术,对比线性插值法和锁相环(PLL)跟踪法的优劣,为电机控制领域的工程师提供实用指南。通过STM32F407和CubeMX的实例,详细探讨两种方法的实现细节、性能对比及优化策略,帮助在不同应用场景下做出最优选择。

weixin_30855761的博客 563

80MHz~100MHz频谱分析仪设计

由理论分析可知,经过乘法器后输出的信号为频率为w1+w2的高频信号和w1-w2的低频信号,除了想要采样的直流信号外,最小的信号频率为100kHz。因此,经过一系列推导可以得到该滤波器的元件C1,C2,C3,R1,R2的近似值分别为:C1=2.36nF,C2=32.1nF,C3=1.07nF,R1=1.39k,R2=2.84k。AK,此时的频率w2即为被测信号的频率,待测信号源电压幅度为,因此为了能达到直流采样的设计,我们将本振源的频率输出范围做成80~110 MHz,提高了题目的频率要求。

qq_48771816的博客 5243

【大模型推理】工作负载的弹性伸缩

推荐采用 并发请求数(Concurrency) 或 队列深度(Queue Size) 结合GPU监控指标(显存/算力利用率),并依托Knative KPA、Fluid缓存、优先级调度等技术实现高效弹性伸缩[citation:6][citation:7][citation:8]。QPS无法体现这种资源消耗累积效应[citation:6]。并发数的本质:是实时反映资源占用的瞬时状态量,而非速率指标,尤其适合单次请求资源消耗大、处理时间长的业务(如LLM推理)[citation:1][citation:6]。

王尚权 qq:2515162716 1185

手眼标定搞定了,手眼矩阵不知道怎么用?快戳!!

手眼标定得到手眼矩阵到底该咋用? 大家好,我是小鱼。上几期给大家分享了关于手眼标定的方法,如果还有不清楚如何让进行手眼标定的同学可以参考下面的文章: 机器人手眼标定都能搞不定?快戳,最好用的手眼标定库!!! 很多同学做完了手眼标定之后得到了手眼矩阵,但是不知道怎么用于程序当中去,还有很多同学搞不清楚各个坐标系之间的关系,今天小智就给大家讲讲手眼矩阵的使用问题。 一、手眼矩阵为什么会长的不一样? 做完手眼标定,得到的手眼矩阵,有可能会长的不一样,这是因为旋转变换是有很多种表示方法的。 1.旋转的表

生活不止眼前的苟且 5344

自定义Usecase/Pipeline

Summary of Custom Usecase and Pipeline Configuration in SA8650 QCX Framework This article elaborates on the complete process of customizing a new Usecase and Pipeline based on the SA8650 QCX framework to meet OEM and Tier1 customization requirements, with

qq_39257814的博客 930

北斗导航 | ChatGPT之RTK、RTD、ARAIM算法原理及程序代码(ChatGPT看你怎么回答,附部分代码)

ChatGPT之RTK、RTD、ARAIM算法原理及程序代码

尘世冰封的专栏 3679

游戏开发:逻辑与渲染分离技术解析

游戏开发中逻辑与渲染分离的架构设计 本文系统阐述了游戏开发中逻辑与渲染分离的设计原则与实践方法。文章首先定义了核心概念:逻辑层负责游戏规则与状态,渲染层处理视觉表现,二者通过数据模型层进行通信。通过历史回顾,揭示了从早期混合架构到现代分层设计的演变过程。 在技术实现层面,文章详细分析了分离架构的优势:性能优化、流畅度控制、测试便利性、扩展灵活性以及团队协作效率。提供了Unity和Unreal两大引擎的具体实现方案,包括代码示例、分层模型和最佳实践。特别探讨了网络同步、客户端预测、插值处理等关键技术难点。 文

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1063

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: Java实现基于邻接表的图的深度和广度遍历
下一篇: Java实现基于邻接表的图的几个应用
Coder_py
博客等级 码龄10年 106粉丝 258原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值