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

本文介绍了使用Java NIO构建的图形用户界面(GUI)聊天室。包括登录界面、服务端和客户端的实现,展示了如何结合NIO进行多用户交互。
摘要由CSDN通过智能技术生成

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.ne
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值