android socket 网络数据传输

原文:http://blog.sina.com.cn/s/blog_726233070100nqw7.html

讲解一下android socket ,包括获取数据包,拆包,解包的过程。

有时候应用程序需要从网络上收发一些数据,软件的底层是用socket实习的,android操作系统的内核是linux,开发语言是java,刚好数据存储结构和以c构建的服务器大小头是相反的,所以取到c做的服务器数据时,需要转换一下数据的大小头。这里也一并讲解。

 

首先是socket

//实例化一个socket(指定服务器ip和端口号,建立有效的TCP/IP的连接)

Socket socket = new Socket(String ip,int  port);

//注意socket实例一个套接字的过程是阻塞的,有必要在辅助线程完成

 

//获取socketStream

OutputStream outStream = socket.getOutputStream();
    InputStream inputStream = socket.getInputStream();

//这里在啰唆几句,socketStream 只要不close,这个socket就会一直连接,也就是我们所说的长连接

//输入输出流的定义是:从流输入到内存,叫输入流,反之输出。

//流就相当于一个管道,里面有没有数据,跟流本身没有任何关系


//发送一组byte[]出去

outStream .write(b, 0, len);

//b为一组byte(java中一个byte=16bit,排列顺序为大头在前 索引(也可以叫做游标)从0开始到len结束


outS tream  .flush();

//更新流的通道


//接受byte[] 和拆包  注意:这里的包头为4个字节,前2字节为length,后两字节为type

int leftLength = 0;

byte[] b = new byte[4096];

while ((leftLength += inputStream.read(b, leftLength, 2048)) > 0) {

     //read是一个阻塞的线程,所以不必考虑这里出现死循环,有数据则返回值>0
         Log.e(">>>>>>>>>>>>>>>>>>>>>>>>", "leftLength  >>>  leftLength = " + leftLength);
         // 此处开始拆包

    while (true) {
            if (leftLength < 4)
                 break;
             else {
                 int length = ByteHandle.getShort(b, 0);
                 if (length <= leftLength) {
                      int type = ByteHandle.getShort(b, 2);
                      byte[] buf = new byte[length]; 
                      System.arraycopy(b, 0, buf, 0, length);
                      System.arraycopy(b, length, b, 0, leftLength - length);
                      leftLength -= length;
                          switch (type) {
                          case REG_REQ_CNF_MSG:
                          // 登陆证实消息
                              boolean state = (int) buf[4] == 0 ? true : false;
                              Log.e("message","type = REG_REQ_CNF_MSG  >>>  length = "

                               + length + "   " + state);

                          break;
                          case QUERY_CONF_MSG:
                          // 心跳证实消息
                               Log.e("message", "type = QUERY_CONF_MSG  >>>  length = " + length);
                               break;
                          }
                          continue;
                   } else
                          break;
                   }

        }
      }

 

讲解一下:ByteHandle.getShort函数

这是我自定义的函数,因为byte[]数据时从c的服务器获取到的,bit编码小头在前,在java中需要转换为大头在前,转换方法如下:(主要思路是计算其偏移量)

public static short getShort(byte[] b, int index) {
      return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));
    }

 

public static long getLong(byte[] b, int index) {
       return ((((long) b[index + 7] & 0xff) << 56)
            | (((long) b[index + 6] & 0xff) << 48)
            | (((long) b[index + 5] & 0xff) << 40)
            | (((long) b[index + 4] & 0xff) << 32)
            | (((long) b[index + 3] & 0xff) << 24)
            | (((long) b[index + 2] & 0xff) << 16)
            | (((long) b[index + 1] & 0xff) << 8)

        | (((long) b[index + 0] & 0xff) << 0));
    }

 

举两个例子,多了不想打字了,根据数据类型,将byte重新排列,转换成大头在前,然后return相应数据类型的(object)byte[]就ok了

 

 

后记:这一部分虽然很简单,但是有很多细节的东西容易搞错,所以注释相对比较细致。看过的一定要留下你的足迹哦,任何意见和建议欢迎给出!明天继续!

 


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值