简易聊天程序教程(一)自定义异常和消息格式

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686

如果有什么问题,欢迎留言。

自定义异常的目的是为了更好的表示出错的原因,能够针对不同的异常执行不同的处理。

异常的自定义是简单的,只是简单的继承了Exception类。下面给出所有聊天程序的异常类的基类的ChatException的定义:

package SimpleChat;

public class ChatException extends Exception{

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	public ChatException() {}

	public ChatException(String desc) {
		super(desc);
	}

}

聊天程序的所有异常都应该继承这个类。这个的实现是很简单的,稍微懂点Java的都能看懂。

消息格式的定义也是简单的。

为什么不用现有的http协议来通信?

因为http协议对于这个程序来说,有很多东西是冗余的,因此为了提高利用率,这个我自定义了一个参考http协议的消息格式。

举一个请求消息的例子:

from:wapoonx

to:xwp

command:send

hello

以上就是一个发送消息的请求,from字段表明这个消息是从谁发送过来的。to这个字段表明要发送给谁,也就是接收方是谁。command这个字段表明要执行的命令。以一个空行为标志。隔开正文和头部字段。在这个例子中正文是hello。服务器会根据command字段,从请求报文中选取自己想要的信息。

举一个响应消息的例子:

code:0

description:success

(注意这里是空的正文)

以上是一个响应消息的格式,code这个字段代表的是一个响应码,这个响应码代表着服务器执行响应的客户请求的结果,0代表成功,其他代表出错。description是响应消息的描述。不同的描述在客户端可能有不同的处理。

下面给出请求报文的类的定义:

package SimpleChat;
import java.util.Map;
import java.util.TreeMap;

public class RequestMessage {
	private String from = "";
	private String to = "";
	private String command = "";
	private String rawContext = "";

	public RequestMessage() {

	}

	public RequestMessage(String raw) {
		parse(raw);
	}

	public String getFrom() {
		return from;
	}

	public String getTo() {
		return to;
	}

	public String getCommand() {
		return command;
	}

	public String getContext() {
		return rawContext;
	}

	public void setFrom(String f) {
		from = f;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public void setCommand(String cmd) {
		this.command = cmd;
	} 

	public void setContext(String con) {
		rawContext = con;
	}

	public String Format() {
		String res = "from:" + from+ "\r\n";
		res += "to:" + to + "\r\n";
		res += "command:" + command + "\r\n\r\n";
		res += rawContext;

		return res;
	} 

	private void parse(String raw) {
		String[] temp = raw.split("\r\n\r\n");
		String[] fields = temp[0].split("\r\n");

		if (temp == null || fields == null) {
			return ;
		}

		for (int i = 0; i < fields.length; ++i) {
			if (fields[i].indexOf("from:") == 0) {
				from = fields[i].substring("from:".length());
			}
			else if (fields[i].indexOf("to:") == 0) {
				to = fields[i].substring("to:".length());
			}
			else if (fields[i].indexOf("command:") == 0) {
				command = fields[i].substring("command:".length());
			}
		}
		if (temp.length == 2) {
			rawContext = temp[1];
		}
	}

	public static Map<String, String> parseContext(String rawContext) throws ChatMessageException {
		if (rawContext == null || rawContext.equals("")) {
			return new TreeMap<String, String>();
		}

		Map<String, String> context = new TreeMap<String, String>();
		String[] temp = rawContext.split("\r\n");

		for (int i = 0; i < temp.length; ++i) {
			String[] res = temp[i].split(":");
			if (res.length == 2) {
				context.put(res[0], res[1]);
			} else {
				throw new ChatMessageException("response message is invaild. context's format error");
			}
		}

		return context;
	}

	public Map<String, String> parseContext() throws ChatMessageException {
		return parseContext(this.rawContext);
	}
}

上面这个类的理解难点在于parse函数。其实也很好懂。就是在上面举得请求消息报文中的字段和正文分析出来。报文的头部会有很多个字段,然后每个字段会被有一个对应的值,可能为空。parse函数解析请求报文有下面几个步骤:

1.使用String的splite函数,将正文和头部分割开。因为正文和头部之间值有连续的两个CRLF(\r\n)的。整个报文中也只有这个地方会出现连续的两个CRLF。

2.头部中的每个字段都是要满足下面形式:字段之间用一个CRLF隔开,字段中的形式是fieldname:value,因此很容易的就可以再用splite函数处理头部字段。

3.正文的内容会根据请求报文中的command字段的不同,具有不同的含义。这里的parseContext函数只是提供了最基本的一种解析方式。这里的解析基于下面的假设:每行只有一个键值对(就是类似头部字段中的内容那样)。在这个假设下,解析正文,并且把正文放到Map容器中。返回给调用者。

当然,请求报文还有格式化自己的功能,因此有一个Format函数,来将请求报文的内容格式化,方便以流的形式输出给服务器端。需要注意的是,客户端和服务器端的请求报文类是相同的。响应报文类也是完全相同的。响应报文类的作用也和请求报文相似。因此不再赘述。

时间: 2024-12-28 18:40:12

简易聊天程序教程(一)自定义异常和消息格式的相关文章

简易聊天程序教程(四)客户端基本功能

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686 如果有什么问题,欢迎留言. 客户端的基本功能是根据服务器给出的接口逐步来实现的.客户端的设计流程是清晰的.简化的思考流程如下图所示: 当然,实现的时候就要考虑比较多的细节,比如在注册的时候,注册失败怎么办,登陆的时候,账号密码不匹配怎么办.但总的流程就是这样子的. 从上面的流程可以看出了,客户端的窗口模块分下面几个(附上动作的解析): 1 登陆窗口模块: 登陆窗口需要提供两个

简易聊天程序教程(三)服务器的多线程

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686 如果有什么问题,欢迎留言. 如果一个服务器只能为两个用户提供服务器,那就真的是太渣了.很多时候,聊天的客户都会大于两个.因此需要提高并发量. 在Java中使用多线程还是很方便的.我在这个服务器程序使用的是实现Runnable接口的方法来定义自己的多线程操作.通过重写run方法,来实现自己的多线程操作. 每个线程都会有一个client成员变量,这个成员变量用来记录客户端的Soc

简易聊天程序教程(六)主窗口和聊天窗口

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686 如果有什么问题,欢迎留言. 主窗口用的是JList控件,在显示了登陆的跟人信息之后,接下来就是好友的列表. 为了方便以后拓展 ,我把好友的信息封装在FriendInformation中,FriendInformation类的定义也很简单的,都能看懂. 下面来逐步分析一下MainWin类: MainWin中比较重要的是事件的监听: 好友列表中的右键菜单的监听: JMenuIte

简易聊天程序教程(二)服务器的基本功能

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686 如果有什么问题,欢迎留言. 我设计的时候是先从服务器端开始设计的,服务器端先给出接口,然后客户端针对接口编程. 在说服务器的代码之前先说说数据库的设计吧. 数据的设计是简单的,只有两个表: create database SimpleChat; CREATE TABLE IF NOT EXISTS Account ( username varchar(50) NOT NULL

简易聊天程序教程(五)客户端的登陆和注册窗口

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686 如果有什么问题,欢迎留言. 其实大家也能想到,登陆和注册窗口其实很相似的,而注册窗口总是比登陆窗口多一些内容. 先来说说登陆窗口.登陆窗口的界面如下图: 登陆窗口继承字Dialog类,而不是继承自JFrame类.登陆窗口显示在屏幕中间,通过下面的方法就可以达到效果: setLocationRelativeTo(null); 在构造函数中调用这个方法,就能显示在屏幕中央,如果参

基于C# Winform的简易聊天程序[第一篇-两端通信]

程序简介 本聊天程序支持局域网内部客户端与服务端之间的互相通信. 原理 启动服务端后,服务端通过持续监听客户端发来的请求,一旦监听到客户端传来的信息后,两端便可以互发信息了.服务端需要绑定一个IP,用于客户端在网络中寻找并建立连接.信息发送原理:将手动输入字符串信息转换成机器可以识别的字节数组,然后调用套接字的Send()方法将字节数组发送出去.信息接收原理:调用套接字的Receive()方法,获取对端传来的字节数组,然后将其转换成人可以读懂的字符串信息. 界面设计 - 服务端 IP文本框 na

PHP制作简易聊天程序

近几天来,突然在查阅PHP中文手册时,看到了用PHP制作聊天室的示例,于是一时心血来潮也用PHP写了一个简易的WEB聊天室应用,在写聊天室的过程中,我遇到的问题其实不算很多,因为用php制作聊天室的原理是非常简单的,也许这与我自身思考问题的方式有关,我往往喜欢把任何看似复杂的东西简单化,我相信表面复杂的事物,其实都蕴含着简易原理,我的这种思维模式在这次WEB聊天应用的制作中起到了作用,下面我就将PHP制作WEB聊天室的原理给大家做一个介绍: 首先我们要建立一个WEB框架,这个框架也就是利用HTM

.Net学习笔记----2015-07-06(简易聊天程序)

直接上代码,注释俺写了不少,留着参考 服务端: 1 namespace sever 2 { 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 11 { 12 13 } 14 15 16 private void bt

C# 异步通信 网络聊天程序开发 局域网聊天室开发

Prepare 本文将使用一个NuGet公开的组件技术来实现一个局域网聊天程序,利用组件提供的高性能异步网络机制实现,免去了手动编写底层的困扰,易于二次开发,扩展自己的功能. 在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台输入下面的指令安装: Install-Package HslCommunication NuGet安装教程  http://www.cnblogs.com/dathlin/p/7705014.html 技术支持QQ群:592132