`
tmdpzc
  • 浏览: 13788 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java NIO 学习 聊天室程序 (2)

阅读更多
有了Command 接口,我们可以定义一些命令:
这些命令也代表了一些基本的需求

    1. @pub 向聊天室中发广播消息
    2. @quit 退出聊天室   , 如果断线,聊天室可以自动将与客户端的连接断开
    3. @listmember  查看聊天室中的所有人
    4. @login  username password  以用户名和密码登陆服务器
    5. @regist  username password 注册用户
    6. @usr  username|socket address 向特定用户发消息


有了以上需求的话,我们就需要定义一些数据结构:
首先定义会员类:
package com.tcl.chat;

import java.lang.Thread.State;

/**
 * 会员类
 * 
 * @author tmdpzc
 * 
 */
public class Member {
	private String mUsername;
	private String mPassword;

	private MemberState mState;
	/**
	 * 定义会员的状态
	 * @author tmdpzc
	 *
	 */
	static class MemberState {
		public static final int OFFLINE = 0;
		public static final int UNLOGIN = 1;
		public static final int ONLINE = 2;
		public int state = 0;

		public MemberState() {
			// do nothing
		}

		public void setState(int state) {
			this.state = state;
		}

	}

	public boolean login(String username, String password) {
		if (this.mUsername.equals(username) && this.mPassword.equals(password)) {
			online();
			return true;
		}
		return false;
	}
	public void connected(){
		mState.setState(MemberState.UNLOGIN);
	}
	
	private void online() {
		mState.setState(MemberState.ONLINE);
	}

	public void offline() {
		mState.setState(MemberState.OFFLINE);
	}

	public Member(String username, String password) {
		super();
		this.mUsername = username;
		this.mPassword = password;
		this.mState = new MemberState();
	}

	public String getUsername() {
		return mUsername;
	}

	public void setUsername(String username) {
		this.mUsername = username;
	}

	public String getPassword() {
		return mPassword;
	}

	public void setPassword(String password) {
		this.mPassword = password;
	}

}


定义一个存储会员的接口,可以理解为这是一个key-value 的数据库:
package com.tcl.chat;

public interface MemberStorage {
	public boolean register(Member m);
	public boolean has(String m);
	public Member get(String name);
}


既然是简单的NIO 聊天室,就使用一个Map来存储Member的数据好了
一个实现MemberStorage接口的类
package com.tcl.chat.impl;

import java.util.HashMap;

import com.tcl.chat.Member;
import com.tcl.chat.MemberStorage;

public class MemberStorageImpl implements MemberStorage{
	private HashMap<String, Member> mStorage;
	
	public  MemberStorageImpl(int size){
		mStorage = new HashMap<String, Member>(size);
	}

	@Override
	public boolean register(Member m) {
		if (has(m.getUsername())) {
			return false;
		}else {
			mStorage.put(m.getUsername(), m);
		}
		return true;
	}

	@Override
	public boolean has(String name) {
		Member m = mStorage.get(name);
		if (m == null) {
			return false;
		}else {
			return true;
		}
	}

	@Override
	public Member get(String name) {
		return mStorage.get(name);
	}
}

在ChatServer类中有这么几个Map:
Map<String, SocketChannel> mChannelMap;//socket address 到 SocketChannel的映射
Map<String, Member>  mLoginMemberMap; //socket address  到 member的映射;
MemberStorage mMemberStorage; //所有会员的记录;

这些基础设施建立好了,后面就可以实现我们的命令了,也就是具体的功能。
首先是PubCmd:
package com.tcl.chat.command;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

import com.tcl.chat.ChatServer;

public class PubCmd extends Command {

	@Override
	public void handleCmd(SelectionKey key, ChatServer server, String[] args)
			throws IOException {
		SocketChannel sc = (SocketChannel) key.channel();
		StringBuilder sb = new StringBuilder();
		if (args.length <= 1) {
			return;
		} else {
			for (int i = 1; i < args.length; i++) {
				sb.append(args[i]);
			}
		}

		String pub_msg = sc.socket().getRemoteSocketAddress() + ": "
				+ sb.toString();
		System.out.println(pub_msg);
		Iterator<SelectionKey> it = key.selector().keys().iterator();
		while (it.hasNext()) {
			SelectionKey sKey = (SelectionKey) it.next();
			if ((sKey != key) && (sKey != server.getServerKey())) {
				String address = ((SocketChannel) sKey.channel()).socket()
						.getRemoteSocketAddress().toString();
				if (server.getLoginMemberMap().get(address) == null) {
					return;// 未登陆成功的终端看不到消息
				}
				if (sKey.attachment() == null) {
					sKey.attach(pub_msg);
				} else {
					String at = (String) sKey.attachment();
					sKey.attach(at + pub_msg);
				}
				sKey.interestOps(sKey.interestOps() | SelectionKey.OP_WRITE);
			}
		}
	}

}

再来RegistCmd
package com.tcl.chat.command;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

import com.tcl.chat.ChatServer;
import com.tcl.chat.Member;
import com.tcl.chat.utils.LogUtil;

public class RegistCmd extends Command {
	private static ByteBuffer ERROR = ByteBuffer
			.wrap("Error regist username and password".getBytes());
	private static ByteBuffer SUCCESS = ByteBuffer.wrap("Regist success"
			.getBytes());

	@Override
	public void handleCmd(SelectionKey key, ChatServer server, String[] args)
			throws IOException {
		// TODO Auto-generated method stub
		LogUtil.i("Regist CMD :");
		SocketChannel sc = (SocketChannel) key.channel();
		LogUtil.e("args length " + args.length);
		if (args.length == 3) {
			String username = args[1];
			String password = args[2];
			Member mb = new Member(username, password);
			boolean flag = server.getMemberStorage().register(mb);
			if (flag) {
				sc.write(SUCCESS);
				SUCCESS.flip();
				return;
			}
		}
		sc.write(ERROR);
		ERROR.flip();//要注意,ByteBuffer要 调用filp才能在第二次的时候重新发送
		return;
	}
}

分享到:
评论

相关推荐

    java NIO 学习 聊天室程序 (3)

    在这个“Java NIO 学习 聊天室程序”项目中,我们将深入探讨NIO如何用于创建一个聊天室程序。这个程序可能包含以下几个关键部分: 1. **服务器端**:服务器端使用NIO的ServerSocketChannel监听客户端连接。当新的...

    JAVA NIO 聊天室程序

    **JAVA NIO 聊天室程序** 在Java编程领域,网络编程是一个重要的部分,而NIO(Non-blocking Input/Output)是Java提供的一种高效、非阻塞的I/O模型,它极大地提升了处理大量并发连接的能力。这个"JAVA NIO 聊天室...

    java NIO socket聊天室

    2,运行client.bat启动客户端,可以打开编辑,ip,和端口号 3,自己发送的信息,自己是看不到的,运行多个客户端,其他的客户端可以看得到的 4,修改封装http做成短连接处理,就是一个小型的webserver,或者结合...

    基于NIO的Java聊天室2

    在本项目"基于NIO的Java聊天室2"中,我们深入探讨了如何利用Java的非阻塞I/O(New Input/Output,NIO)框架来实现一个多人在线聊天室。NIO是一种高效的I/O模型,它允许程序在不阻塞主线程的情况下处理输入和输出操作...

    非GUI聊天室基于javaNIO

    服务端程序基于javaNIO,客户端程序基于旧IO,读完&lt;&lt;javaNIO&gt;&gt;后,导入eclipse即可运行,支持多人在线聊天,上下线通知.PS:非GUI程序,毕竟javaSwing用的少,不懂的地方大家可以一起讨论,评论必回!

    基于NIO的聊天室

    在这个基于NIO的聊天室项目中,我们可以通过分析`Server.java`、`Client.java`和`NioUtil.java`这三个文件来理解NIO的核心概念和实现方式。 首先,`Server.java`文件通常包含了服务器端的主逻辑。在NIO中,服务器会...

    java多线程程序设计:Java NIO+多线程实现聊天室

    java多线程程序设计:Java NIO+多线程实现聊天室 Java基于多线程和NIO实现聊天室 涉及到的技术点 线程池ThreadPoolExecutor 阻塞队列BlockingQueue,生产者消费者模式 Selector Channel ByteBuffer ProtoStuff 高...

    java基于NIO选择器Selector的多人聊天室

    在这个"java基于NIO选择器Selector的多人聊天室"项目中,开发者利用NIO的核心特性构建了一个允许多个客户端同时进行交互的聊天平台。 首先,我们需要了解NIO的基本组件。在Java NIO中,`Selector`是核心角色,它...

    JAVA综合实验2聊天室

    这个"JAVA综合实验2聊天室"项目旨在让学生理解网络编程的基本原理,特别是如何利用Java实现客户端和服务器之间的通信,以及如何设计多用户交互的系统。下面,我们将详细分析这个项目的各个方面。 首先,Java是一种...

    java聊天室(绝对经典)

    在"JAVA聊天室程序.rar"中,你可能会看到一个基于Swing或JavaFX的图形用户界面(GUI)的实现,这使得用户可以直接在窗口中输入和查看消息。而在"java+Sockt聊天室.rar"中,可能侧重于网络通信的细节,展示了如何通过...

    java聊天室程序代码

    Java聊天室程序代码是基于Java编程语言实现的一个多人实时交流平台。这个聊天室的核心功能包括用户注册、登录、发送和接收消息。通过分析提供的压缩包文件名称,我们可以推测出其可能采用了一些并发处理和队列操作的...

    JAVA 开发Java聊天室程序(java)130226

    在本项目"JAVA 开发Java聊天室程序(java)130226"中,我们将深入探讨如何使用Java语言开发一个实时的、多用户交互的聊天室应用。这个项目涉及了多个关键的Java编程概念和技术,包括网络编程、多线程、并发控制以及...

    基于Socket的Java聊天室程序

    Java聊天室程序是一种基于Socket通信技术的多用户交互平台,它允许多个...通过学习和实践这个Java聊天室程序,开发者可以深入理解网络编程、多线程编程以及GUI开发等关键技能,对于提升Java应用开发能力具有重要意义。

    Java即时通讯聊天室

    综上所述,"Java即时通讯聊天室"项目涵盖了网络编程、多线程、安全存储、用户交互等多个核心知识点,是学习和实践Java技术的一个良好平台。通过对这些功能的实现,开发者能够深入理解TCP/IP通信、数据加密、并发控制...

    多线程精品资源--Java NIO+多线程实现聊天室.zip

    在这个“多线程精品资源--Java NIO+多线程实现聊天室”的压缩包中,我们可以推测它包含了一套关于如何使用Java NIO和多线程技术来创建一个实时聊天应用的教程或示例代码。 首先,多线程是Java中并行处理的基础。...

    JavaNIO教程高清

    Java NIO(New I/O)是Java提供的一套新的输入/输出API,自Java 1.4版本起作为标准...Java NIO为处理高性能网络和文件I/O提供了一个强大的工具集,对于需要优化I/O性能的应用程序来说,Java NIO是一个不可或缺的选择。

    Java+Swing聊天室

    5. **网络编程**:聊天室需要通过网络连接进行通信,因此可能使用了Java的Socket编程或者更高层次的API如Java NIO(非阻塞I/O)或Java.net包中的其他类。客户端和服务器之间通过TCP/IP协议交换数据。 6. **数据结构...

    Java聊天室程序(java).zip

    Java聊天室程序是一种基于Java编程语言实现的网络通信应用,它允许用户通过互联网进行实时文本交流。这个压缩包“Java聊天室程序(java).zip”很可能包含了一系列源代码文件、配置文件和其他必要的资源,用于构建一个...

    聊天室基础项目资料_socket聊天室_聊天室_java项目_socket_

    【标题】"聊天室基础项目资料_socket聊天室_聊天室_java项目_socket_" 涉及的是基于Java的Socket编程技术,用于实现一个TCP/IP通信的即时聊天室。在这个项目中,开发者将学习如何利用Java的Socket类来创建客户端和...

Global site tag (gtag.js) - Google Analytics