学java有四个多月的时间了。目前研究到了通信这方面,也是java比较核心的一方面。和以往的学习方法一样,做了个简陋的即时通信来提高理解。
下面一步步的分析即时通信系统的实现。
[list]
首先。也是最终重要的一步定通信协议。那么何为通信协议?我理解就是通信消息的格式,试想一下如果没有通信协议,所有的通信软件都能相互通信,那么QQ能与飞信用户聊天,魔兽世界能登录地下城。。~~~因此协议是重要的一步,而且是需要详细紧密考虑的一步,因为它涉及到通信系统的稳定性和可扩展性。。
下面是xmpp协议的基本格式:
<MyQQ><type>类型</type><body消息></body></MyQQ>
当然协议是自定义的,只要符合这种格式,内容自定义了。
由于目前做的只是简陋的通信系统,我的协议也是相当的简单:
引用
服务器发送协议
登录确认<MyQQ><type>loginConfirm</type><consequence>1/0</consequence>
<ID>帐号</ID><password>密码</password><name>用户名</name></MyQQ>
1代表登录成功 0代表帐号或密码错误
注册确认<MyQQ><type>registerConfirm</type><consequence>1/0</consequence>
</MyQQ> 1代表注册成功 0代表帐号已存在注册失败
发送在线客户作为好友<MyQQ><type>friendlist</type><IDS>
帐号,帐号,帐号</IDS><names>用户名,用户名,用户名</names></MyQQ>
客户端发送协议
登录请求<MyQQ><type>login</type><ID>帐号</ID><password>密码</password></MyQQ> 服务器收到后分析发送确认消息
注册请求<MyQQ><type>register</type><ID>帐号</ID><password>密码</password><name>用户名</name></MyQQ> 同上
发送消息<MyQQ><type>chat</type><senderID>发送者帐号</senderID><recieverID>接受者帐号</recieverID><senderName>发送者用户名</senderName><recieverName>接受接用户名</recieverName><message>消息内容</message></MyQQ> 服务器分析对象转发
发送震动窗体<MyQQ><type>shock</type><senderID>发送者帐号</senderID><recieverID>接受者帐号</recieverID><senderName>发送者用户名</senderName><recieverName>接受接用户名</recieverName></MyQQ> 服务器分析对象转发在协议中我们实现了登录,注册,登录验证,注册验证,发送好友列表,发送聊天消息,发送窗体震动的基本功能。下面我就根据这些简单协议来实现基本功能。
然后,就是服务器和客户端的建立。
[*]
/**
[*] * 建立配置服务器的方法
[*] * @param port 端口号
[*] */
[*] public void setUp(int port){
[*]
[*] try {
[*] serverSocket = new ServerSocket(port);
[*] System.out.println("服务器已建立");
[*] } catch (IOException e) {
[*] // TODO Auto-generated catch block
[*] e.printStackTrace();
[*] System.out.println("端口已占用");
[*] }
[*] }
[*] /**
[*] * 等待客户端接入的方法
[*] */
[*] public void waitForClient(){
[*] try {
[*] sSocket = serverSocket.accept();
[*] System.out.println("有客户端进入");
[*] ServerClient serverClient = new ServerClient(sSocket);
[*] } catch (IOException e) {
[*] // TODO Auto-generated catch block
[*] e.printStackTrace();
[*] }
[*] }
我想这点真的有些多此一举,不过要把这个简陋通信系统讲清楚还是提一下。
这里值得注意的是sSocket = serverSocket.accept();这段代码。这句代码使服务器阻塞直到有客户机接入为止。这里有必要提一下通信中另一个常见的阻塞语句——ins.read(),从网络流中读取数据,一直阻塞知道流中有数据可以读取为止。
再次,就是对接收到消息的分析也是通信中最麻烦最核心的内容。这里我们首先要做的是要分析,当服务器或客户端读取到哪个字节后算是读完了一整条消息(我认为这是XMPP协议的一个缺陷,当读完一整条消息后进行分析才不易出错。而当传输大文件是这是相当不明智的,而要转用字节流协议)。我们可以这样分析,每当服务器或客户端读取一个字节时,我们就把所有读到的字节转成字符串,看字符串是否是以</MyQQ>结尾(当然如果你自定义协议的末尾不是</MyQQ>就以自己的为结尾)。
[*]
// 没有读到结束一直读取字节转为字符串
[*] while (!messageRead.endsWith("</MyQQ>")) {
[*] try {
[*] byteList.add((byte) read());
[*] } catch (IOException e1) {
[*] // TODO Auto-generated catch block
[*] // 读取出现异常关闭客户机对应的服务器
[*] e1.printStackTrace();
[*] close();
[*]
[*] break;
[*] }
[*] messageRead = new String(listToArray(byteList));
[*] }
[*] System.out.println("服务器读到消息末尾跑出了循环" + messageRead);
[*] // 跑出循环服务器分析发送或转发数据 之后字符串赋值""
[*] MessageAnalyse.messageType(this);
引用
其中byteList是一个字节队列用来存放读到的字节,listToArray字节队列转成字节数组的方法,messageType是分析消息类型的方法
之后要进行的就是要分析消息类型,消息的发送者,消息的接收者……为了得到这些内容,可以利用String的一个方法split(String regex, int limit) 来拆分字符串。
[*]
/**
[*] * 分割字符串的方法
[*] *
[*] * @param message
[*] * 要分割的字符串
[*] * @param reference
[*] * 分割的间隔字符串
[*] * @return 返回分割出的内容
[*] */
[*] public static String divideMessage(String message, String reference) {
[*] message = (message.split("<" + reference + ">", 0))[1];
[*] message = (message.split("</" + reference + ">", 0))[0];
[*] System.out.println("分割字符串的到的内容是" + message);
[*] return message;
[*]
[*] }
引用
我把他们封装成了一个易于我使用的方法。
经过对字符串的分析,系统就能知道,这是一条什么消息,是谁发来的消息,消息该发给谁……
其四,就是客户端接收到消息后的响应,这个可以根据自己的设计来响应消息。比如好友上下线消息(界面上的好友列表),比如收到聊天消息(显示到界面)……由于这些不是通信系统中的主要内容这里就不做介绍。
引用
总之一句话,东西是死的,人是活的。程序变成什么样是自己设计的,关键是有思路。
最后,是我在通信是遇到的问题。
[list]
[*]1、乱码问题 这一点在我的博客 http://ml5858258-sina-com.iteye.com/blog/958747有介绍。
[*]2、通信的的异常 这一点在我的博客 http://ml5858258-sina-com.iteye.com/blog/943799
[*]3、内存泄漏。导致此原因是由于,客户端关闭,而服务器端还在死循环的读取。不停地抛出socket reset的异常。看过问题2博客大家都会知道这是个什么异常。解决方法如下:
[*][*]
try {
[*][*] byteList.add((byte) read());
[*][*] } catch (IOException e1) {
[*][*] // TODO Auto-generated catch block
[*][*] // 读取出现异常关闭客户机对应的服务器
[*][*] e1.printStackTrace();
[*][*] close();
[*][*] }
[*]引用
close()是我自定的关闭连接的方法。这样就不会死循环抛异常了。
[/list]
[/list]由于界面过于丑陋,这里就不贴图了。等到完成的项目出炉后在来发表。
下面是简陋通信的源码供广大爱好者们一共学习。
分享到:
相关推荐
基于XMPP协议的即时通信系统服务器集群的研究,陈武,杨世达,本文描述了在实现基于xmpp协议的即时通信系统的服务器集群时遇到的关键性问题,从安全、性能和通用性方面考虑提出了解决方案,重��
基于XMPP协议的Android即时通信系统设计
初步学习XMPP协议,并完成了一个基于XMPP的简单即时通信Demo。
Android 基于XMPP协议IM聊天实现(客户端+服务端) 源码
该资源 基于xmpp协议 以asmack为第三方源码包,以openfire为服务器, 实现了 asmack 注册、登录、添加好友、删除好友、一对一聊天 的功能。 未完待续
基于XMPP协议的即时通信类数据节点重要性分析,牟磊,孙卓,当前针对移动通信核心网数据的分析,大多是基于运营商的语音业务数据等应用数据,而对于IP数据进行数据挖掘与分析的研究工作较少�
基于XMPP协议的类似QQ的即时通信demo 简单实现了 注册,登录,添加好友,删除好友,好友的通信 包括发文本,图片和声音。
不定时更新项目
本文以LBS系统、Android平台、XMPP即时通信协议、定位技术以及电子地图技术为基础,设计了基于XMPP协议的融合导航定位服务与通信服务的移动导航定位应用系统,具有重要的现实意义。
不定时更新项目,bug肯定有,如果你发现也可以告诉我
详细分析了即时通信系统的研究现状,在本项目的基础上提出应用需求。在XMPP协议的基础上,利用gloox库开发即时通信客户端,并实现了与Openfire服务器的互联。
Ⅺ咿P协议的即时通信系统,文件传输只是作为系统的最重要 的组成部分,用于传输普通的文件及在系统中用到的数字签名 文件。基于)m但P协议的文件传输也是基于Ⅺv儿流的传输方 式传输数据,为以后不同风格代码和外来...
主要包括如下几篇文章:XMPP_协议介绍;采用XMPP与GPRS网络的远程控制系统及其应用;基于XMPP的即时通信网关应用研究;基于XMPP的农业远程监测和诊断平台的研究;基于XMPP协议的即时通讯系统的研究
Jabber 最有优势的就是他的通信协议。他可以和多种即时通讯对接。比如有第三方插件,能让jabber用户和MSN 、Yahoo Messager、ICQ..... 对聊;下面是来自 jabber.org官方的原文 Jabber is best known as "the Linux ...
XM(eXtensible Messaging and Presence Protoc01)可扩展消息与出席协议技术便是其中较为活跃的一种即时通信技术。由于即时通信工具在企业中的应用给企业的运营管理带来诸多便利,因而在企业中的应用越来越广泛,具有...
初步学习XMPP协议,并完成了一个基于XMPP的简单即时通信Demo。
基于XMPP的P2P即时通信系统的研究及实现.kdh 基于SIMPLE和XMPP协议的移动IM研究.pdf XMPP研究与应用.pdf XMPP协议研究及其在IM系统群组通信中的应用.pdf XMPP协议分析及客户端开发.nh XMPP_3920_最靠谱的中文翻译...
由于项目需要做一个基于XMPP协议的Android通讯软件。故开始研究XMPP。 XMPP协议采用的是客户端-服务器架构,所有从一个客户端发到另一个客户端的消息和数据都必须经过XMPP服务器转发,而且支持服务器间DNS的路由,也...