iPhone和ESFramework通信的Demo

        这里做一个iPhone和ESFramework通信的Demo,iPhone也是个客户端,是客户端就注定它要去访问服务器,从那里获取数据。而常见的数据访问方法有两种,第一种方法,将对象以json或xml这两种格式序列化成字串,通过调用WebService的基于Web服务器的通信。第二种方法是使Client和Server建立socket连接,将对象序列化后的字串或byte流,通过socket发送给对方。相对第一种方法,基于socket的通信更加高较,安全,节省流量。


  以前都是能过get/post调用web服务器的接口获取数据的,也能很好的满足业务的需求。可现在手上的项目,对客户端和服务端的性能要求都太高,以之前的技术积累跟本搞不定,我很上火啊,跟我一起做务端的哥们也很不容易,他还要处理负载均衡,分布式,数据库优化,图片存储。我一想头就大,还好我是做客户端的,只管调用服务端的通信接口就成了。但项目还得做啊,不做项目日子没法过是吧!〜我跟我那个做Server的哥们想了个招,用以有的通信框架,重复造轮子不现实,就们两个人自己搭一个通信服务器解决以上的问题,不大可能,估计没造出来,我们就走人啦。我是不行,那哥们也得练。就这样,我们选择了ESFramework,ESFramework就在园子里,是一个很强大的通信框架,我对作者很是崇拜加敬仰啊,真天人也!有关ESFramework的介绍还请看作者的Blog


  基本的情况我是介绍了,下面就看我们什么走好第一步吧,我要和服务端建立连接,我要给它发消息!!


  这里我要用下ESFramework4.0的Demo 下载地址可以来这里,以下是对作者博文的引用


     ESFramework4.0 Rapid Demo 源码 (开发环境VS2005,最后上传:2011.04.25) (关于该Demo的详细介绍请参见这里


  本demo是一个简单的IM聊天程序,并且展示了Rapid引擎最基础的功能:消息同步调用、掉线通知、断线重连等功能。


  OK,我们的Server就用Demo里面的,其实里面还有客户端,客户端是.net平台下的,我们不用它,我们用iPhone。


  最早我看到这个Demo的时候我就想模拟它的.net客户端发的消息跟服务端进行通信。当时的想法是先要知道客户端都向服务端发了些什么,于是我开始抓包。


  这里我用的是一个叫smsniff.exe的工具,它的全名是SmartSniff 1.77,当时没记它的下载地址,要是你想用它可以Google一下,肯定有得下。


  启动Server,再开启smsniff.exe,通过客户端登录服务器,smsniff.exe这个东西就能抓到Client发给Server的包,其内容如下图:


     


  这两段隔开的分别是Client发给Server的登录请求和Server返回来的登录结果,看到了byte流就是看到了与服务端建立连接的希望,虽然当时不知里面的内容是啥,但我已经看到了右边的aa01那个就是登录时的用户名。这是明文啊,没有加密啊。当时就比着上面的byte流用iPhone模拟器给Server发了相同的byte流,得到了同样的反回结果,具体的实现 我放在这里,有兴趣的朋友可以下载。


  有关上面具体的登录协议是什么,之后我有问过作者,下面我来标注一下。


  前两位 FF FF 这是一个ushort 类型的变量,它叫StartToken 值为0xFFFF, 用于标识这条消息


  接着的 74 00 也是一个ushort ,它的名字叫 MessageType 它的16进制值是 74,把它换成10进制就是116


  接着 01 00 00 00 这是一个int型变量 它占4个字节,是这条消息的ID,它的值为1


  到此为止,大家可以看下,这两条消息前8个字节是一样的。你发现了么? 哈哈!! 从这个索引位为8的开始的后4位 0c 00 00 00,存了int型的MessageBodyLen, 因为字节流这东西不像json,xml这种有标签,有结点的,可以找,byte流这东西谁知道它有多长啊,这里就用这个int型的变量去标识这条消息的Body体有多长,0x0c 就是 12,Body体有12个字节


  索引位12 的 04 是一个byte型的变量,它存了UserID的长度,这里UserID是 aa01 长度是4


  索引位13 开始的后11位 存了String型的变量UserID 即然只有11位最一定要限制UserID的长度,这里的UserID不足11,就要用0补齐


  这样就到了索引24 02 这是一个byte变的变量,它存了DestUserID的长度,所谓DestUser就是我们这条消息要发给谁,消息接收者的ID. 这里的DestUserID的长度只有2


  索引25开始到索引36处结束 同UserID一样是String类型的DestUserID ,到此处,消息头结束。OK,看花眼没,当时我搞这一段的时候是抄纸上一点点对的。


  下面是消息体,消息体简单,在消息头中我说看到了,这条消息只有12个字节,那段 08 00 00 00 是一个int型的变量,用于标识密码的长度,这个示例的Demo是不用密码的,密码为空,但它又有字节长度限制这里用0全补满了,就是我们看到是12个字节长的Body体了。下面的登录结果消息我就不解析了,有心的朋友也能看得懂,不就是 _0 又发给 aa01一条消息么。


  下面的代码是我在ios平台对以上数据类型做序列化的 方法 在这里列一下:

     - (void)addUnsignedShort:(unsigned short)uShort{

const int size = 2;

union {

unsigned short us;

short ss;

unsigned char buffer[size];

} u;

u.us = uShort;

[messageData appendBytes:u.buffer length:size];

  }

  - (void)addInt:(int)iInt{

const int size = 4;

union {

int sl;

unsigned char buffer[size];

} u;

u.sl = iInt;

[messageData appendBytes:u.buffer length:size];

  }

  - (void)addUnsignedChar:(unsigned char)uChar{

unsigned char *buffer;

buffer = &uChar;

[messageData appendBytes:buffer length:1];

  }


   messageData 是 NSMutableData 类型的变量。
  
   ok,有话我们下次说,我先睡了,多谢读完本文的兄弟,好运!
原文地址:https://www.cnblogs.com/upwifi/p/2152692.html