热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

移动开发中的通信架构(四)

这篇文章讲解真正的网络请求类HttpClient,它负责打开网络链接,获取数据,把数据存放于一个字节数组,让Response

这篇文章讲解真正的网络请求类HttpClient,它负责打开网络链接,获取数据,把数据存放于一个字节数组,让Response解析。

以下是代码:

package app.http; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection; import app.program.GameConst; /** * 功能&#xff1a; * * 打开网络链接&#xff0c;获取数据&#xff0c;把数据存放于一个字节数组&#xff0c;让Response解析 */ public class HttpClient { // 注: HttpsConnection继承自HttpConnection private HttpConnection conn &#61; null; private InputStream inputStream &#61; null; private OutputStream outputStream &#61; null; private Request request &#61; null; int msgId; public HttpClient(int _msgId) { msgId &#61; _msgId; } public Response getResponse(Request request) throws Exception { if (request &#61;&#61; null) { return null; } try { this.request &#61; request; Response resp &#61; new Response(); // 打开链接 makeConnection(); // 设置参数 setProperty(); // 写入内容 setContent(); // 打开输入流 makeInputStream(); // 得到响应码 resp.responseCode &#61; conn.getResponseCode(); if (resp.responseCode !&#61; HttpConnection.HTTP_OK) { return null; } String strContentLength &#61; conn.getHeaderField("content-length"); if (strContentLength !&#61; null) { resp.contentLength &#61; Integer.parseInt(strContentLength); } resp.analysisData(readResponse(), true); return resp; } catch (Exception e) { e.printStackTrace(); throw e; } finally { this.request &#61; null; cleanup(); } } private void makeConnection() throws Exception { conn &#61; (HttpConnection) Connector.open("http://", Connector.READ_WRITE, true); } private void makeInputStream() throws Exception { inputStream &#61; conn.openInputStream(); } private void makeOutputStream() throws Exception { outputStream &#61; conn.openOutputStream(); } /** * 参数设置 * * &#64;throws Exception */ private void setProperty() throws Exception { conn.setRequestMethod(HttpConnection.POST); } public void setContent() throws Exception { if (request.getContent() !&#61; null) { conn.setRequestProperty("Content-Length", String.valueOf(request.getContent().length)); makeOutputStream(); outputStream.write(request.getContent()); } } /** * 从网络流中读取数据&#xff0c;存放于字节数组中 * * &#64;return * &#64;throws Exception */ private byte[] readResponse() throws Exception { try { byte[] data &#61; null; if (conn !&#61; null && inputStream !&#61; null) { int len &#61; (int) conn.getLength(); // 读取模式1&#xff1a;直接获取数据长度 if (conn.getRequestMethod().equals(HttpConnection.HEAD)) { return null; } if (len <&#61; 0) { // 读取模式2&#xff1a;从Http连接头获取数据长度 String bodyLength &#61; null; try { bodyLength &#61; conn.getHeaderField("content-length"); } catch (IOException e) { e.printStackTrace(); } if (bodyLength !&#61; null) { try { len &#61; Integer.parseInt(conn.getHeaderField("Body-Length")); } catch (Exception e) { e.printStackTrace(); } } } if (len > 0) { int actual &#61; 0; int bytesread &#61; 0; data &#61; new byte[len]; while ((bytesread !&#61; len) && (actual !&#61; -1)) { actual &#61; inputStream.read(data, bytesread, len - bytesread); if (actual >&#61; 0) { bytesread &#43;&#61; actual; } } if (bytesread &#61;&#61; 0) { return null; } else if (bytesread
重点关注方法是&#xff1a;

public Response getResponse(Request request) throws Exception&#xff1b;

代码里面涉及了Response和StructResponse&#xff0c;它们的代码页一并罗列&#xff1a;

package app.http; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; import app.program.Globe; /** * 返回信息的解析方法类&#xff0c;和StructRequest对应 */ public class StructResponse { private DataInputStream in; private ByteArrayInputStream bin; private Hashtable hash; private Vector vec; private int size; public StructResponse(byte[] data) { bin &#61; new ByteArrayInputStream(data); in &#61; new DataInputStream(bin); } public StructResponse(byte[] data, boolean bTradeCipher) { hash &#61; new Hashtable(); vec &#61; new Vector(); if (!bTradeCipher) { readTradeData(data); } else { readTradeCipherData(data); } this.getTable(); } private boolean bTable &#61; false; private int tableIndex &#61; 0; // 表格数据的列数 private void readTradeData(byte[] data) { int i &#61; 0; try { for (; i 0) { String s &#61; new String(data, 0, i, "UTF-8"); putInHash(s); } break; } else if (data[i] &#61;&#61; 0x04) { bTable &#61; false; String s &#61; new String(data, 0, i, "UTF-8"); vec.addElement(s); if (tableIndex &#61;&#61; 0) { tableIndex &#61; vec.size(); } break; } } String s &#61; new String(data, 0, i, "UTF-8"); putInHash(s); } catch (Exception ex) { ex.printStackTrace(); } if (data.length - i - 1 > 0) { byte[] nData &#61; new byte[data.length - i - 1]; System.arraycopy(data, i &#43; 1, nData, 0, data.length - i - 1); readTradeData(nData); } } private void readTradeCipherData(byte[] data) { for (int i &#61; 0; i &#61; 0) { String s1 &#61; s.substring(0, index); String s2 &#61; s.substring(index &#43; 1, s.length()); this.hash.put(s1, s2); } } public String getHashData(String key) { return (String) hash.get(key); } public String[][] getTable() { if (tableIndex <&#61; 0) { return null; } int line &#61; vec.size() / this.tableIndex; String[][] tmp &#61; new String[line][tableIndex]; for (int i &#61; 0; i

package app.http; import java.util.Hashtable; import java.io.*; /** * 按照私有协议&#xff0c;解析数据&#xff0c;和Request对应&#xff0c;把最终解析结果存放于一个hash中&#xff0c;存放格式是 消息码--消息内容 */ public class Response { private Hashtable hash &#61; new Hashtable(); public int responseCode; public int contentLength; private static final byte START_FLAG &#61; (byte) &#39;{&#39;; private static final byte END_FLAG &#61; (byte) &#39;}&#39;; private static final byte OTHER_FLAG &#61; (byte) &#39;:&#39;; public Response() { } /** * 分析数据 解析TYPE和真正数据content * * &#64;param data * byte[] */ public void analysisData(byte[] _data, boolean isStart) { StructResponse struct &#61; new StructResponse(_data); byte[] data &#61; null; try { while (isStart) { int v &#61; struct.readByte(); if (v &#61;&#61; -1) { throw new IOException(" DATA"); } if (v &#61;&#61; START_FLAG) { break; } } int type &#61; struct.readShort(); struct.readByte(); // 0 标志位 struct.readByte(); // 0 标志位 data &#61; struct.readByteArray(); byte tmp &#61; (byte) struct.readByte(); if (tmp &#61;&#61; END_FLAG) { hash.put(Integer.toString(type), data); } else if (tmp &#61;&#61; OTHER_FLAG) { hash.put(Integer.toString(type), data); analysisData(struct.getOthers(), false); } else { throw new IOException("BAD DATA"); } } catch (IOException ex) { ex.printStackTrace(); } } public int getResponseCode() { return responseCode; } public int getContentLength() { return contentLength; } public byte[] getData(int key) { return (byte[]) hash.get(Integer.toString(key)); } public int getResponseNum() { return hash.size(); } }




推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
author-avatar
趣校区导购网
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有