学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基于XML流协议,通过TCP连接传输数据。它包括三...
开发一个基于XMPP的即时通信程序需要深入理解XMPP协议的原理和实现,熟悉相关库(如Smack或libstrophe)的使用,以及具备良好的编程能力。同时,为了提高用户体验,还需要考虑跨平台兼容性、界面设计以及性能优化等...
通过以上介绍,我们可以看到,基于XMPP协议的多端即时通讯方案不仅能够实现不同即时通信软件之间的互联互通,还能支持多种设备类型,为用户提供更加便捷、高效的沟通体验。同时,选择开源的Openfire作为服务器端,...
### 基于XMPP协议的Android即时通信系统设计 #### 概述 随着移动通信技术的飞速发展,智能手机的普及以及移动互联网的应用日益广泛,即时通信(Instant Messaging, IM)已成为人们日常生活中不可或缺的一部分。...
【即时通信(IM)技术概述】 ...通过对"improject源码"的分析和实践,开发者不仅可以掌握XMPP即时通信的实现,还能提升在Android平台上的项目开发能力。同时,持续关注项目更新,可以获取最新的技术趋势和最佳实践。
### .NET平台基于XMPP协议的即时消息服务端简单实现 #### 一、XMPP协议简介 XMPP(可扩展消息与存在协议)是一种基于XML的开放标准协议,主要用于即时通讯(IM)系统,文件传输,游戏引擎,物联网(IoT),以及...
在这个基于XMPP协议的Android即时通信应用项目中,开发者构建了一个允许用户进行即时消息传递、状态更新和群组聊天的平台。项目的源码更新版本意味着它在不断改进,修复已知问题,同时可能添加新的功能或优化性能。 ...
即时通讯(Instant Messaging...通过以上知识点,可以了解到基于XMPP协议的多端即时通讯系统的设计、搭建、实现与应用。从协议本身的优势到实际搭建过程中的细节,都涵盖了建立一个即时通讯系统所需的关键技术和步骤。
在本资源中,我们关注的是基于XMPP(Extensible Messaging and Presence Protocol)协议的即时通信实现,名为"asmackDemo"。XMPP是一种开放标准,它基于XML流,被广泛用于构建实时通讯应用,包括聊天、VoIP、协作和...
本文研究与实现了一个基于XMPP协议的即时通信系统,特别是针对文件传输功能进行了深入探讨。XMPP(可扩展消息处理协议)是一种基于XML(可扩展标记语言)的开放标准,用于实时通信系统。它能够支持即时消息传递、...
基于XMPP协议的Android消息推送设计与实现 本文主要介绍了基于XMPP协议的Android消息推送设计与实现。消息推送已经成为手机端产品信息实时发布和网络营销的一种重要手段。XMPP协议作为Android系统消息推送的主要...
【基于XMPP协议的Gloox底层库开发的即时通讯Qtalk源码】是一个使用C++编写的项目,它利用了Gloox库来构建一个即时通讯应用。Gloox库是一个开源的实现,完全遵从XMPP(Extensible Messaging and Presence Protocol)...
1. **XMPP协议**:XMPP是一种开放标准的实时通信协议,它基于XML流传输,广泛应用于即时消息、在线状态跟踪和文件传输。XMPP的核心设计使其能够处理大量并发连接,支持多用户聊天、群组功能和跨域通信,因此非常适合...
### 基于XMPP协议的P2P即时通讯软件设计——关键技术与实现 #### XMPP协议概述 XMPP(可扩展消息处理协议)是一种基于XML的即时通讯协议,它支持实时消息传输、存在信息、文件共享等功能。XMPP协议因其开放性、可...